2012-10-01 231 views
2

在试图改善一些OpenCL的计算性能,我用一个clEnqueueWriteBuffer呼叫OpenCL运行的分析功能,以及紧随其后的clEnqueueNDRangeKernel(取决于以前的数据转院):clEnqueueWriteBuffer究竟做了什么?

clEnqueueWriteBuffer(cmdq, cl_buf, CL_FALSE, 0, size, data, 0, NULL, &write_ev); 
clEnqueueNDRangeKernel(cmdq, ker_with_cl_buf_as_input_param, 2, NULL, 
    work_sze, local_sze, 1, &write_ev, &ker_ev); 

这里是由clGetEventProfilingInfo返回(我中减去初始时间并转换为微秒):

  QUEUED SUBMIT START  END END-START 
write_ev  0 113.952 120.448 211.136  90.688 
ker_ev 130.016 132.608 217.280 515.200  297.920 

我的问题是:

  1. 为什么clEnqueueWriteBuffer在内存传输启动或提交之前没有返回?
  2. 更重要的是,为什么转移实际需要很长时间?

在我看来,只要内存传输可以立即开始,就可以获得22%的性能。 在实际进行传输之前,clEnqueueWriteBuffer是否会复制另一个主机内存区域中的数据?

其他信息:

我使用特斯拉M2090 GPU CUDA的4.1框架。

缓冲创建以前使用:

cl_buf = clCreateBuffer(my_context, CL_MEM_READ_ONLY, size, NULL, NULL); 

编辑:clEnqueueReadBuffer不表现出这种行为。

回答

3

您可以尝试使用固定内存,如NVidia OpenCL Best Practices Guide的第3.1.1节中所述。

他们没有提到在使用可分页内存时是否执行了复制,但可能会发生。

+0

是的,我认为你是对的,当使用固定内存时,这个大的延迟消失。所以驱动程序可能会复制数据,或者做一些其他的事情来从常规内存中传输,这需要一些时间...... –

2

在开始异步复制之前,写入操作应进行一些检查。该检查包括参数中的有效缓冲区类型,缓冲区不对齐,缓冲区的分配以及写入等。

在clEnqueueWriteBuffer函数中,只有数据的原始副本是异步的,但准备不是。

+0

而阅读不? –

+0

@natchouf这个读操作没有相同的检查,也没有保留缓冲区来编写 – Zhen

+0

,这对缓冲区的第一次使用(其中写入实际需要更长时间)肯定是正确的,但是我对后续的重用有怀疑。 .. –