OpenCL / C ++主机代码并发运行和内存维护

时间:2014-08-17 16:11:49

标签: c++ opencl

我正在尝试使用OpenCL来加速预先存在的C ++模拟的某些部分。目前,我选择了一个循环,在每个模拟时间步长上运行1k-1M次迭代。

根据我目前的理解,我必须在调用内核之前使用enqeueWriteBuffer手动将数据写入内核缓冲区。在调用内核之前,我必须每次都执行此操作,以便内核对正确的数据进行操作。是否有可能使缓冲区上的数据写入与现有的C ++代码同步发生?

就目前而言,在请求内核之前,现有的C ++代码执行另一个循环,这需要我的内存传输所需的时间。在调用之前,此循环不会更改或影响我必须写入内核的数据。是否可以在此期间同步进行内存传输?我更愿意主持运行循环,同时还将数据同时写入缓冲区,节省了宝贵的仿真时间。

谢谢!

2 个答案:

答案 0 :(得分:1)

我真的没有看到一个大问题。

您只需要异步复制数据,同时执行另一项操作。这可以通过对clEnqueueWriteBuffer()的非阻塞调用来完成。 此外,您甚至可以并行运行内核并继续在CPU中执行C ++循环。没有必要等待,因为内核的数据独立于其他C ++循环数据。

//Get the data for OpenCL ready
...

//Copy it asynchronously
clEnqueueWriteBufer(queue, buffer, CL_FALSE, size, ptr_to_data);
clFlush(); //Ensure it gets executed (not really needed)
//Run the kernel (asynchronously as well)
clENqueueNDRangeKernel(...);

//Do something else
... 
//Everything that is clEnqueueXXXX is run in the GPU, and does not take CPU cycles.

//Get the data back
clEnqueueReadBufer(...);

//Wait for the GPU to finish
clFinish(...); //Or, by making the read blocking

答案 1 :(得分:0)

首先,措辞更正:您没有将数据写入内核,而是将其写入设备,内核稍后会使用它。

要做你想做的事,你需要两个命令队列,一个用于数据,另一个用于内核执行。然后使用事件来确保内核不会运行直到数据传输完成。

在AMD卡上,这可以满足您的需求。在NVIDIA上,必须使用clCreateBuffer和CL_MEM_ALLOC_HOST_PTR标志分配源内存,以使clEnqueueWriteBuffer异步。查看他们的示例:https://developer.nvidia.com/opencl#oclCopyComputeOverlap