内存对象OpenCL的基地址 [英] Base Address of Memory Object OpenCL
问题描述
我想使用 OpenCL 在GPU上遍历一棵树,因此我将树组装在主机上的连续块中,并更改所有指针的地址,以便在设备上保持一致,如下所示:
I want to traverse a tree at GPU with OpenCL, so i assemble the tree in a contiguous block at host and i change the addresses of all pointers so as to be consistent at device as follows:
TreeAddressDevice =(size_t)BaseAddressDevice +((size_t)TreeAddressHost-(size_t)BaseAddressHost);
我要内存缓冲区的基地址: 在主机上,我为缓冲区分配内存,如下所示: cl_mem tree_d = clCreateBuffer(...);
I want the base address of the memory buffer: At host i allocate memory for the buffer, as follows: cl_mem tree_d = clCreateBuffer(...);
问题在于cl_mems是跟踪数据内部表示形式的对象.从技术上讲,它们是指向对象的指针,但它们不是指向数据的指针.从内核内部访问cl_mem的唯一方法是通过setKernelArgs将其作为参数传递.
The problem is that cl_mems are objects that track an internal representation of the data. Technically they're pointers to an object, but they are not pointers to the data. The only way to access a cl_mem from within a kernel is to pass it in as an argument via setKernelArgs.
Here http://www.proxya.net/browse.php?u=%3A%2F%2Fwww.khronos.org%2Fmessage_boards%2Fviewtopic.php%3Ff%3D37%26amp%3Bt%3D2900&b=28 i found the following solution, but it doesnot work:
__kernel void getPtr( __global void *ptr, __global void *out )
{
*out = ptr;
}
可以如下调用
代码:
...
cl_mem auxBuf = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(void*), NULL, NULL );
void *gpuPtr;
clSetKernelArg( getterKernel, 0, sizeof(cl_mem), &myBuf );
clSetKernelArg( getterKernel, 1, sizeof(cl_mem), &auxBuf );
clEnqueueTask( commandQueue, getterKernel, 0, NULL, NULL );
clEnqueueReadBuffer( commandQueue, auxBuf, CL_TRUE, 0, sizeof(void*), &gpuPtr, 0, NULL, NULL );
clReleaseMemObject(auxBuf);
...
现在,"gpuPtr"应该包含GPU内存空间中"myBuf"开头的地址.
Now "gpuPtr" should contain the address of the beginning of "myBuf" in GPU memory space.
解决方案很明显,我找不到它?创建缓冲区时如何获取指向设备内存的指针?
The solution is obvious and i can't find it? How can I get back a pointer to device memory when creating buffers?
推荐答案
这是因为在OpenCL模型中,主机内存和设备内存是不相交的.设备内存中的指针在主机上将没有任何意义.
It's because in the OpenCL model, host memory and device memory are disjoint. A pointer in device memory will have no meaning on the host.
您可以使用clEnqueueMapBuffer将设备缓冲区映射到主机内存.映射会将设备同步到主机,而取消映射会将主机重新同步到设备.
You can map a device buffer to host memory using clEnqueueMapBuffer. The mapping will synchronize device to host, and unmapping will synchronize back host to device.
更新.正如您在注释中解释的那样,您希望将树结构发送到GPU.一种解决方案是将所有树节点存储在数组中,用数组中的索引替换指向节点的指针.
Update. As you explain in the comments, you want to send a tree structure to the GPU. One solution would be to store all tree nodes inside an array, replacing pointers to nodes with indices in the array.
这篇关于内存对象OpenCL的基地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!