背景:
我有一个名为“buildlookuptable”的内核,它进行一些计算并将其结果存储在名为“dense_id”的int数组中。
创建cl_mem对象:
作为一个小型内存对象,dense_id 可以通过复制来提高执行时间,但需要付出一定的内存代价。
问题: 在“buildlookuptable”内核执行后,我想在设备端复制结果数组 dense_id。直接的方式是在主机端使用 ClEnqueueReadBuffer 获取 dense_id,创建一个新的 cl_mem 对象并将其推回到设备端。是否有一种方法可以在“buildlookuptable”完成后复制 dense_id,而无需再次将其复制到主机端?
如果需要,我可以在此添加更多代码。我尝试只使用所需部分,因为我不想让您淹没在无关的代码中。
创建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]);
执行时间:66毫秒 没有基于编译器的向量化。
但是,如果我将该行更改为:
result_tuples += (dense_id[bucket] - dense_id[bucket]);
执行时间:2毫秒 通过编译器矢量化(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,而无需再次将其复制到主机端?
如果需要,我可以在此添加更多代码。我尝试只使用所需部分,因为我不想让您淹没在无关的代码中。
(dense_id[bucket] - dense_id[bucket]);
很可能被编译器简化为0,这就是你的速度来源,而不是内存读取。哦,而且复制也没有任何好处。你应该在这些情况下使用本地内存。 - DarkZeros