【问题标题】:Opencl Buffer and kernel executionOpencl 缓冲区和内核执行
【发布时间】:2012-10-10 00:58:04
【问题描述】:

取自 OpenCL by Action

下面的代码实现了如图所示的目标。 它创建两个缓冲区对象,并使用 clEnqueueCopyBuffer 将缓冲区 1 的内容复制到缓冲区 2。

然后 clEnqueueMapBuffer 将 Buffer 2 的内容映射到主机内存,memcpy 将映射的内存传输到一个数组中。

我的问题是如果我不在代码中编写以下行,我的代码是否仍然有效:

    err = clSetKernelArg(kernel, 0, sizeof(cl_mem),  
                 &buffer_one);                     
    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), 
                  &buffer_two);              
    queue = clCreateCommandQueue(context, device, 0, &err);
    err = clEnqueueTask(queue, kernel, 0, NULL, NULL);     

内核是空白的,它什么也不做。设置内核参数和入队任务需要什么?

...
float data_one[100], data_two[100], result_array[100];
cl_mem buffer_one, buffer_two;
void* mapped_memory;
...

 buffer_one = clCreateBuffer(context,           
  CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,             
  sizeof(data_one), data_one, &err);       
 buffer_two = clCreateBuffer(context,                  
  CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,       
  sizeof(data_two), data_two, &err);  



  err = clSetKernelArg(kernel, 0, sizeof(cl_mem),  
                 &buffer_one);                     
  err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), 
                  &buffer_two);              
 queue = clCreateCommandQueue(context, device, 0, &err);
 err = clEnqueueTask(queue, kernel, 0, NULL, NULL);     



 err = clEnqueueCopyBuffer(queue, buffer_one,  
  buffer_two, 0, 0, sizeof(data_one),           
  0, NULL, NULL);            



  mapped_memory = clEnqueueMapBuffer(queue, 
  buffer_two, CL_TRUE, CL_MAP_READ, 0,            
  sizeof(data_two), 0, NULL, NULL, &err);
  memcpy(result_array, mapped_memory, sizeof(data_two));       
  err = clEnqueueUnmapMemObject(queue, buffer_two, 
  mapped_memory, 0, NULL, NULL);                  
  }

...

【问题讨论】:

    标签: opencl


    【解决方案1】:

    我相信调用 enqueueTask 的目的是确保数据实际驻留在设备上。当使用CL_MEM_COPY_HOST_PTR 标志时,内存可能仍保留在主机端,直到内核需要它为止。因此,将任务入队可确保将内存带到设备中。这也可能发生在某些设备上,但不会发生在其他设备上。

    您可以通过检测您的代码并测量运行任务所花费的时间来测试这个理论,无论是任务有参数还是没有参数。如果任务需要更长的时间处理参数,那么这很可能是正在发生的事情。

    【讨论】:

    • 谢谢克利。你能详细说明一下你怎么能这么说“当使用 CL_MEM_COPY_HOST_PTR 标志时,内存可能仍然保留在主机端,直到内核需要它。”有任何支持这一点的参考资料吗?
    • 坦率地说,这是我能看到的在代码中出现 enqueueTask 的唯一原因。我很想知道这是否真的如此。它也可能取决于实现。 OpenCL 没有指定数据必须立即发送到设备,因此理论上可以在主机端进行缓冲。
    猜你喜欢
    • 2012-06-23
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多