2017-06-30 1 views
-7

Je veux apprendre le C# opencl.net pour accélérer le code par GPU, ce code est dans le site https://habrahabr.ru/post/124873/, je ne peux pas comprendre le sens, tout le monde peut l'expliquer, et n'importe où je peux en apprendre davantage sur le opencl.net, merci beaucoup.qui comprend ce code C# opencl.net?

private void button4_Click(object sender, EventArgs e) 
{ 
    //Установка параметров, инициализирующих видеокарты при работе. В Platforms[1] должен стоять индекс 
    //указывающий на используемую платформу 
    ComputeContextPropertyList Properties = new ComputeContextPropertyList(ComputePlatform.Platforms[1]); 
    ComputeContext Context = new ComputeContext(ComputeDeviceTypes.All, Properties, null, IntPtr.Zero); 

    //Текст програмы, исполняющейся на устройстве (GPU или CPU). Именно эта программа будет выполнять паралельные 
    //вычисления и будет складывать вектора. Программа написанна на языке, основанном на C99 специально под OpenCL. 
    string vecSum = @" 
    __kernel void 
    floatVectorSum(__global float * v1, 
    __global float * v2) 
    { 
    int i = get_global_id(0); 
    v1[i] = v1[i] + v2[i]; 
    } 

    "; 
    //Список устройств, для которых мы будем компилировать написанную в vecSum программу 
    List<ComputeDevice> Devs = new List<ComputeDevice>(); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[0]); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[1]); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[2]); 
    //Компиляция программы из vecSum 
    ComputeProgram prog = null; 
    try 
    { 

    prog = new ComputeProgram(Context, vecSum); prog.Build(Devs, "", null, IntPtr.Zero); 
    } 

    catch 

    { } 

    //Инициализация новой программы 
    ComputeKernel kernelVecSum = prog.CreateKernel("floatVectorSum"); 

    //Инициализация и присвоение векторов, которые мы будем складывать. 
    float[] v1 = new float[100], v2 = new float[100]; 
    for (int i = 0; i < v1.Length; i++) 
    { 
    v1[i] = i; 
    v2[i] = 2 * i; 
    } 
    //Загрузка данных в указатели для дальнейшего использования. 
    ComputeBuffer<float> bufV1 = new ComputeBuffer<float>(Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, v1); 
    ComputeBuffer<float> bufV2 = new ComputeBuffer<float>(Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, v2); 
    //Объявляем какие данные будут использоваться в программе vecSum 
    kernelVecSum.SetMemoryArgument(0, bufV1); 
    kernelVecSum.SetMemoryArgument(1, bufV2); 
    //Создание програмной очереди. Не забудте указать устройство, на котором будет исполняться программа! 
    ComputeCommandQueue Queue = new ComputeCommandQueue(Context, Cloo.ComputePlatform.Platforms[1].Devices[0], Cloo.ComputeCommandQueueFlags.None); 
    //Старт. Execute запускает программу-ядро vecSum указанное колличество раз (v1.Length) 
    Queue.Execute(kernelVecSum, null, new long[] { v1.Length }, null, null); 
    //Считывание данных из памяти устройства. 
    float[] arrC = new float[100]; 
    GCHandle arrCHandle = GCHandle.Alloc(arrC, GCHandleType.Pinned); 
    Queue.Read<float>(bufV1, true, 0, 100, arrCHandle.AddrOfPinnedObject(), null); 
} 

Répondre

-1
private void button4_Click(object sender, EventArgs e) 
{ 

    ComputeContextPropertyList Properties = new ComputeContextPropertyList(ComputePlatform.Platforms[1]); 
    ComputeContext Context = new ComputeContext(ComputeDeviceTypes.All, Properties, null, IntPtr.Zero); 

    //define a function template that sum two vectors 
    string vecSum = @" 
    __kernel void 
    floatVectorSum(__global float * v1, 
    __global float * v2) 
    { 
    int i = get_global_id(0); 
    v1[i] = v1[i] + v2[i]; 
    } 

    "; 
    //add gpu devices into list for executing the vecSum function defined at last step 
    List<ComputeDevice> Devs = new List<ComputeDevice>(); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[0]); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[1]); 
    Devs.Add(ComputePlatform.Platforms[1].Devices[2]); 
    //define a compute programe with function define and gpu devices specified. 
    ComputeProgram prog = null; 
    try 
    { 

    prog = new ComputeProgram(Context, vecSum); prog.Build(Devs, "", null, IntPtr.Zero); 
    } 


    catch 

    { } 


    ComputeKernel kernelVecSum = prog.CreateKernel("floatVectorSum"); 

    //init the vectors need by the vecSum. 
    float[] v1 = new float[100], v2 = new float[100]; 
    for (int i = 0; i < v1.Length; i++) 
    { 
    v1[i] = i; 
    v2[i] = 2 * i; 
    } 
    //create parametes needed as pass in parameter for vecSum. 
    ComputeBuffer<float> bufV1 = new ComputeBuffer<float>(Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, v1); 
    ComputeBuffer<float> bufV2 = new ComputeBuffer<float>(Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, v2); 
    //pass the parameters in. 
    kernelVecSum.SetMemoryArgument(0, bufV1); 
    kernelVecSum.SetMemoryArgument(1, bufV2); 
    //queue your compute request. 
    ComputeCommandQueue Queue = new ComputeCommandQueue(Context, Cloo.ComputePlatform.Platforms[1].Devices[0], Cloo.ComputeCommandQueueFlags.None); 
    //execute your compute request 
    Queue.Execute(kernelVecSum, null, new long[] { v1.Length }, null, null); 
    //clean the resource and read the result from the queue 
    float[] arrC = new float[100]; 
    GCHandle arrCHandle = GCHandle.Alloc(arrC, GCHandleType.Pinned); 
    Queue.Read<float>(bufV1, true, 0, 100, arrCHandle.AddrOfPinnedObject(), null); 
} 
+0

merci beaucoup! votre réponse est très utile pour moi. –