在CUDA中,我可以启动相同的内核,通过在k上的for循环中调用下面的代码,在同一个数组的不同部分上同时操作:
kernel<<<blkPerGrd, thdPerBlk, 0, stream[k]>>>(in_array + offset, out_array + out_offset)
我想在OpenCL 2.0中使用C ++包装器做同样的事情。我现在的想法是调用在不同命令队列上排队内核,将in_array
和out_array
设置为内核的参数,并将偏移量作为参数传递。所以像这样(在for循环中k):
kernel.setArg(0, in_array);
kernel.setArg(2, in_offset);
kernel.setArg(3, out_array);
kernel.setArg(4, out_offset);
queue[k].enqueueNDRangeKernel(kernel, cl::NullRng, gblRng, lclRange, NULL, NULL);
其中in_array
和out_array
是cl::Buffer
个对象。
这是否有意义还是有更好的方法来处理偏移?我尝试检查cl::Buffer
类是否接受指针算术,但我不认为它。
答案 0 :(得分:0)
您正在做的是将内核分解为多个部分的可接受方式,但还有其他方法可以实现。
就个人而言,我更喜欢通过更改enqueueNDRangeKernel
的参数来启动这些类型的内核。您可能会注意到,您显然已将其中一个参数&#34; null&#34;,或更确切地说,cl::NullRng
。这通常是Offset参数,可以用来做你正在尝试做的事情。
Image img;
std::vector<cl::Event> events;
//Do not perform work on an area larger than 100x100 pixels at a time.
for(int x = 0; x < img.width(); x += 100) {
int end_x = std::min(img.width(), x + 100);
for(int y = 0; y < img.height(); y += 100) {
int end_y = std::min(img.height(), y + 100);
events.emplace_back();
queue.enqueueNDRangeKernel(kernel, cl::NDRange{x, y}, cl::NDRange{end_x - x, end_y - y}, {}, nullptr, &events.back());
}
}
queue.enqueueWaitForEvents(events);