gpt4 book ai didi

c++ - OpenCL 缓冲区分配和映射最佳实践

转载 作者:行者123 更新时间:2023-11-30 17:27:46 28 4
gpt4 key购买 nike

我对使用 OpenCL 映射缓冲区的代码是否正确感到有点困惑。

我有两个示例,一个使用 CL_MEM_USE_HOST_PTR,另一个使用 CL_MEM_ALLOC_HOST_PTR。两者都可以在我的本地计算机和 OpenCL 设备上工作和运行,但我感兴趣的是这是否是进行映射的正确方法,以及它是否应该在所有 OpenCL 设备上工作。我特别不确定 USE_HOST_PTR 示例。

我只对缓冲区/映射特定操作感兴趣。我知道我应该进行错误检查等等。

CL_MEM_ALLOC_HOST_PTR:

// pointer to hold the result
int * host_ptr = malloc(size * sizeof(int));

d_mem = clCreateBuffer(context,CL_MEM_READ_WRITE|CL_MEM_ALLOC_HOST_PTR,
size*sizeof(cl_int), NULL, &ret);

int * map_ptr = clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_WRITE,
0,size*sizeof(int),0,NULL,NULL,&ret);
// initialize data
for (i=0; i<size;i++) {
map_ptr[i] = i;
}

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL);

//Set OpenCL Kernel Parameters
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&d_mem);

size_t global_work[1] = { size };
//Execute OpenCL Kernel
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
global_work, NULL, 0, 0, NULL);

map_ptr = clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_READ,
0,size*sizeof(int),0,NULL,NULL,&ret);
// copy the data to result array
for (i=0; i<size;i++){
host_ptr[i] = map_ptr[i];
}

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL);

// cl finish etc

CL_MEM_USE_HOST_PTR:

// pointer to hold the result
int * host_ptr = malloc(size * sizeof(int));
int i;
for(i=0; i<size;i++) {
host_ptr[i] = i;
}

d_mem = clCreateBuffer(context,CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR,
size*sizeof(cl_int), host_ptr, &ret);

// No need to map or unmap here, as we use the HOST_PTR the original data
// is already initialized into the buffer?

//Set OpenCL Kernel Parameters
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&d_mem);

size_t global_work[1] = { size };
//Execute OpenCL Kernel
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
global_work, NULL, 0, 0, NULL);

// this returns the host_ptr so need need to save it (I assume it always will?)
// although we do need to call the map function
// to ensure the data is copied back.
// There's no need to manually copy it back into host_ptr
// as it uses this by default
clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_READ,
0,size*sizeof(int),0,NULL,NULL,&ret);

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL);

// cl finish, cleanup etc

最佳答案

如果您使用 CL_MEM_ALLOC_HOST_PTR 您有机会 OpenCL 的底层实现可能会使用页面锁定内存

这意味着页面无法换出到磁盘,并且主机和设备内存之间的传输将以 DMA 方式完成,而不会浪费 CPU 周期。因此,在这种情况下,CL_MEM_ALLOC_HOST_PTR 将是最佳解决方案。

nVidia 具有页面锁定(固定)内存功能,他们也应该在 OpenCL 实现中使用它。对于 AMD 来说,不确定他们是否也会这样做。检查here 了解更多详情。

使用 CL_MEM_USE_HOST_PTR 只会让程序员的工作变得更轻松,因此在不太可能的情况下当硬件无法使用页面锁定内存时,您可以使用此选项。

关于c++ - OpenCL 缓冲区分配和映射最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26277268/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com