OpenCL:如何将现有的缓冲区一分为二?

OpenCL:如何将现有的缓冲区一分为二?,opencl,Opencl,假设我碰巧分配了一些OpenCL内存,比如200个浮点值 cl::Buffer newBuf = cl::Buffer(op::CLManager::getInstance(gpuID)->getContext(), CL_MEM_READ_WRITE, sizeof(float) * 200); 现在我想把这个cl::Buffer分成两个对象,一个是前100个float对象,另一个是后续的,这样我就可以将它们传递到两个内核中。我找不到任何资源来解释如何做到这一点 我别无选择,因为我正在

假设我碰巧分配了一些OpenCL内存,比如200个浮点值

cl::Buffer newBuf = cl::Buffer(op::CLManager::getInstance(gpuID)->getContext(), CL_MEM_READ_WRITE, sizeof(float) * 200);
现在我想把这个cl::Buffer分成两个对象,一个是前100个float对象,另一个是后续的,这样我就可以将它们传递到两个内核中。我找不到任何资源来解释如何做到这一点

我别无选择,因为我正在使用的库会返回一个非常大的缓冲区,我更愿意在CPU端将其拆分为更小的cl::Buffers以传递到内核,而不会在拆分过程中产生内存开销

我尝试过这样做,但它有以下缺点:

cl::Buffer newBuf = cl::Buffer(op::CLManager::getInstance(gpuID)->getContext(), CL_MEM_READ_WRITE, sizeof(float) * 200);
cl::Buffer part1 = cl::Buffer((cl_mem)((float*)(newBuf.get())+0),true); // OK
cl::Buffer part2 = cl::Buffer((cl_mem)((float*)(newBuf.get())+100),true); // SEGFAULT

cl_mem对象不是指针,所以不能像在CUDA中使用cudaMalloc返回的指针那样偏移它们

如果您使用OpenCL2.0或更高版本,您可以尝试SVM共享虚拟内存,它提供了一个clSVMAlloc[1]函数,可以返回指针并进行偏移。 请注意,此机制在您的实现中可能会有一些开销

另一种可能在性能方面更好的选择是使用OpenCL子缓冲区[2]。存在一些限制,例如,原点必须与某些设备参数对齐,因此请检查基础设备限制

[1]

[2]