设备上的opencl重复内存对象

opencl duplicate memory object on device

背景: 我有一个名为 "buildlookuptable" 的内核,它进行一些计算并将其结果存储到一个名为 "dense_id"

的 int 数组中

正在创建 cl_mem 对象:

cl_mem dense_id = clCreateBuffer(context, CL_MEM_READ_WRITE, (inCount1) * sizeof(int), NULL, &err); errWrapper("create Buffer", err);

设置内核参数:

errWrapper("setKernel", clSetKernelArg(kernel_buildLookupTable, 5, sizeof(cl_mem), &dense_ids));

dense_ids之后在其他内核中使用。由于糟糕的内存分配,我的性能大幅下降。

下面的内核像这样访问dense_id:

result_tuples += (dense_id[bucket+1] - dense_id[bucket]);

执行时间:66ms 没有基于编译器的矢量化

但是,如果我将行更改为:

result_tuples += (dense_id[bucket] - dense_id[bucket]);

执行时间:2ms 由编译器矢量化(4) geforce 660ti 上的两个内核 运行。

所以如果我删除重叠的内存访问,速度会大大提高。 线程N访问内存N,没有重叠。

为了获得正确的结果,我想复制 cl_mem 对象 dense_id。因此,以下内核中的行将是:

result_tuples += (dense_id1[bucket+1] - dense_id2[bucket]);

而 dense_id1 和 dense_id2 是相同的。 另一种想法是将 dense_id1 的内容移动一个元素。 所以内核行将是:

result_tuples += (dense_id1[bucket] - dense_id2[bucket]);

因为 dense_id 是一个小内存对象,我确信,我可以通过复制它以内存为代价来缩短我的执行时间。

问题: "buildlookuptable" 内核执行后,我想在设备端复制结果数组 dense_id。 直接的方法是在主机端使用 ClEnqueueReadBuffer 来获取 dense_id,创建一个新的 cl_mem 对象并将其推回设备。 有没有办法在 "buildlookuptable" 完成后复制 dense_id,而无需再次将其复制到主机?

如果需要,我可以在此处添加更多代码。我试图只使用必需的部分,因为我不想让你淹没在不相关的代码中。

我尝试了使用 Clenqueuecopybuffer 命令的解决方案,效果如愿。 我的问题的解决方案是:

clEnqueueCopyBuffer(command_queue, count_buffer, count_buffer3, 1, 0, (inCount1 + 1) * sizeof(int), NULL, NULL, NULL);

在不使用另一个内核的情况下,可以仅在设备端复制内存对象。

为此,您必须先在主机端创建另一个 cl_mem 对象:

cl_mem count_buffer3 = clCreateBuffer(context, CL_MEM_READ_WRITE, (inCount1 + 1) * sizeof(int), NULL, &err); errWrapper("create Buffer", err);

因为我不得不等待复制完成,所以我使用了

clFinish(command_queue);

让程序等待其终止

正如 DarkZeros 所暗示的那样,性能增益为 0,因为编译器优化了行

result_tuples += (dense_id[bucket] - dense_id[bucket]);

到 0。

感谢您到目前为止的见解!