有几个字符串,如
std :: string first,second,third; ...
我的计划是将他们的地址收集到char *数组中:
char *addresses = {&first[0], &second[0], &third[0]} ...
并将char **地址传递给OpenCL内核。
有几个问题或疑问:
主要问题是我无法传递指针数组。
有没有什么好的方法可以使用内核代码中的多个字符串而不复制它们但是将它们留在共享内存中?
我在Windows上使用NVIDIA。所以,我只能使用OpenCL 1.2版本。
我无法连接字符串,因为它们来自不同的结构......
修改
根据第一个答案,如果我有这个(例子):
char *p;
cl_mem cmHostString = clCreateBuffer(myDev.getcxGPUContext(), CL_MEM_ALLOC_HOST_PTR, BUFFER_SIZE, NULL, &oclErr);
oclErr = clEnqueueWriteBuffer(myDev.getCqCommandQueue(), cmHostString, CL_TRUE, 0, BUFFER_SIZE, p, 0, NULL, NULL);
我是否需要将char数组 的每个元素从主机内存复制到主机 内存的其他部分(并且新地址对主机是隐藏的)? ?这不合乎逻辑。为什么我不能使用相同的地址?我可以直接从GPU设备访问主机内存并使用它。
答案 0 :(得分:0)
有没有什么好的方法可以使用内核代码中的多个字符串而不复制它们但是将它们留在共享内存中?
不在OpenCL1.2中。自OpenCL 2.0以来,共享虚拟内存概念可用,NVidia目前尚不支持。您需要切换到支持OpenCL 2.0的GPU或OpenCL 1.2将字符串复制到连续的字符数组中并将它们(复制)传递给内核。
编辑:回复您的修改 - 您可以使用:
CL_MEM_ALLOC_HOST_PTR
标志创建所需大小的空缓冲区,然后使用clEnqueueMapBuffer
映射该缓冲区并使用映射返回的指针填充它。之后,使用clEnqueueUnmapMemObject
取消映射缓冲区。CL_MEM_USE_HOST_PTR
标志创建所需大小的缓冲区并将指针传递给您的字符数组。根据我的经验,使用CL_MEM_USE_HOST_PTR
标志创建的缓冲区通常会稍快一些,我认为数据是否真的被复制或取决于实现。但要使用它,您需要首先在主机上准备好您的字符数组。
您基本上需要进行基准测试,看看哪些更快。也不要过多地集中精力进行数据复制,与运行内核所需的时间(当然取决于内核中的内容)相比,这些数据通常是微小的数字(以GB /秒为单位的传输)。