是否定义为从不同内核写入同一缓冲区?
Is it defined to write to the same buffer from different kernels?
我有OpenCL 1.1,一台设备,乱序执行命令队列,
并希望多个内核将它们的结果输出到一个缓冲区到不同的、不重叠的、任意的区域。
可能吗?
cl::CommandQueue commandQueue(context, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);
cl::Buffer buf_as(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, data_size, &as[0]);
cl::Buffer buf_bs(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, data_size, &bs[0]);
cl::Buffer buf_rs(context, CL_MEM_WRITE_ONLY, data_size, NULL);
cl::Kernel kernel(program, "dist");
kernel.setArg(0, buf_as);
kernel.setArg(1, buf_bs);
int const N = 4;
int const d = data_size / N;
std::vector<cl::Event> events(N);
for(int i = 0; i != N; ++i) {
int const beg = d * i;
int const len = d;
kernel_leaf.setArg(2, beg);
kernel_leaf.setArg(3, len);
commandQueue.enqueueNDRangeKernel(kernel, NULL, cl::NDRange(block_size_x), cl::NDRange(block_size_x), NULL, &events[i]);
}
commandQueue.enqueueReadBuffer(buf_rs, CL_FALSE, 0, data_size, &rs[0], &events, NULL);
commandQueue.finish();
如果全局内存地址如您所描述的那样不重叠,写入应该可以正常工作。只需确保两个内核都已完成,然后再将结果读回主机。
我想对此给出官方委员会的回应。我们意识到规范含糊不清,并已进行修改以纠正此问题。
这在 OpenCL 1.x 或 2.0 规则下不 得到保证。 cl_mem 对象仅保证在同步点保持一致,即使仅在单个设备上处理,甚至由 OpenCL 2.0 内核使用 memory_scope_device。 =10=]
OpenCL 2.0 父内核的多个子内核可以在设备范围内共享父 cl_mem 对象。
粗粒度 SVM 对象可以在多个内核之间的设备范围内共享,只要写入的内存位置不重叠。
我认为它没有定义。虽然你说你在软件级别写入非重叠区域,但不能保证在硬件级别访问不会映射到相同的缓存行 - 在这种情况下你会有多个修改版本。
我有OpenCL 1.1,一台设备,乱序执行命令队列, 并希望多个内核将它们的结果输出到一个缓冲区到不同的、不重叠的、任意的区域。 可能吗?
cl::CommandQueue commandQueue(context, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);
cl::Buffer buf_as(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, data_size, &as[0]);
cl::Buffer buf_bs(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, data_size, &bs[0]);
cl::Buffer buf_rs(context, CL_MEM_WRITE_ONLY, data_size, NULL);
cl::Kernel kernel(program, "dist");
kernel.setArg(0, buf_as);
kernel.setArg(1, buf_bs);
int const N = 4;
int const d = data_size / N;
std::vector<cl::Event> events(N);
for(int i = 0; i != N; ++i) {
int const beg = d * i;
int const len = d;
kernel_leaf.setArg(2, beg);
kernel_leaf.setArg(3, len);
commandQueue.enqueueNDRangeKernel(kernel, NULL, cl::NDRange(block_size_x), cl::NDRange(block_size_x), NULL, &events[i]);
}
commandQueue.enqueueReadBuffer(buf_rs, CL_FALSE, 0, data_size, &rs[0], &events, NULL);
commandQueue.finish();
如果全局内存地址如您所描述的那样不重叠,写入应该可以正常工作。只需确保两个内核都已完成,然后再将结果读回主机。
我想对此给出官方委员会的回应。我们意识到规范含糊不清,并已进行修改以纠正此问题。
这在 OpenCL 1.x 或 2.0 规则下不 得到保证。 cl_mem 对象仅保证在同步点保持一致,即使仅在单个设备上处理,甚至由 OpenCL 2.0 内核使用 memory_scope_device。 =10=]
OpenCL 2.0 父内核的多个子内核可以在设备范围内共享父 cl_mem 对象。
粗粒度 SVM 对象可以在多个内核之间的设备范围内共享,只要写入的内存位置不重叠。
我认为它没有定义。虽然你说你在软件级别写入非重叠区域,但不能保证在硬件级别访问不会映射到相同的缓存行 - 在这种情况下你会有多个修改版本。