如上一个答案:不,您根本不需要交换缓冲区。
但是,我不同意提出的答案。该函数clSetKernelArg()
不是线程安全的,并且不设计为在操作循环中调用。
正确的解决方案是创建 2 个使用相同程序和源创建的内核。这种方法更符合 OpenCL 编程理念“一个内核完成一项任务”。拥有许多具有相同代码但不同参数的内核是要走的路。
第一个内核将具有:
kernel1 = clCreateKernel(program, "mykernel", NULL);
clSetKernelArg(kernel1, 0, &buff1);
clSetKernelArg(kernel1, 1, &buff2);
另一个将是:
kernel2 = clCreateKernel(program, "mykernel", NULL);
clSetKernelArg(kernel2, 0, &buff2);
clSetKernelArg(kernel2, 1, &buff1);
这样,您无需在每次迭代时停止执行。您可以简单地运行:
for(int it=0; it<iter; it++){
clEnqueueNDRangeKernel(it%2 ? kernel1 : kernel2, ....);
}
clFinish(command);
这种方法肯定会比更改内核参数更好,更高效,API 调用更少。此外,在某些系统上clSetKernelArgs()
,由于 API 实现不佳,可能是阻塞调用。所以最好尽量避免它们。