clEnqueueWriteBuffer真正做了什么?

时间:2012-10-01 17:28:09

标签: opencl

在尝试提高某些OpenCL计算的性能时,我在clEnqueueWriteBuffer调用上使用了OpenCL运行时的分析功能,并在紧随其后的clEnqueueNDRangeKernel(这取决于之前的数据传输)上使用了:

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. 更重要的是,为什么转移实际提交需要这么长时间?
  3. 在我看来,只要内存传输可以立即启动,就可以获得22%的性能。 在实际进行传输之前,clEnqueueWriteBuffer是否将数据复制到另一个主机内存区域?

    其他信息:

    我在Tesla M2090 GPU上使用cuda 4.1框架。

    先前使用以下方法创建缓冲区:

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

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

写入应该在启动异步复制之前进行一些检查。此检查包括参数中的有效缓冲区类型,缓冲区未对齐,要写入的缓冲区分配等等。

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