OpenCL 子缓冲区主机指针
OpenCL Sub Buffer Host pointer
我创建了一个具有属性 CL_MEM_READ_WRITE 和 CL_MEM_ALLOC_HOST_PTR 的缓冲区。我已将此缓冲区排队到 GPU 内核。 GPU 内核处理给定的输入并填充这些缓冲区。在此过程中 CPU 被等待。我通过使用子缓冲区将缓冲区划分为三个统一的部分来修改此设计。现在GPU填满一个子缓冲区后,CPU就可以开始处理了。这减少了 CPU 等待一个子缓冲区而不是一个完整的帧处理。
我面临的问题是,子缓冲区和缓冲区的映射指针(cpu 侧指针)很奇怪。第一个子缓冲区和缓冲区的映射指针相同。这没关系。但是第二个子缓冲区的映射指针不等于缓冲区的映射指针+第二个子缓冲区的偏移量。我在集成 GPU 型号(Intel HD Graphics 4000)上试过这个。它工作正常。但是当我 运行 在专用显卡设备 (nvidia zotac) 上运行时,我遇到了这个问题。你以前遇到过这样的场景吗。您能否提供一些指示,指出在哪里可以解决此问题。
typedef struct opencl_buffer {
cl_mem opencl_mem;
void *mapped_pointer;
int size;
}opencl_buffer;
// alloc gpu output buffers
opencl->opencl_mem = clCreateBuffer(
opencl->context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
3 * alloc_size, NULL, &status);
if (status != CL_SUCCESS)
goto fail;
// create output sub buffers
for (sub_idx = 0; sub_idx < 3; ++sub_idx) {
cl_buffer_region sf_region;
SubFrameInfo subframe;
sf_region.origin = alloc_size * sub_idx;
sf_region.size = alloc_size;
opencl->gpu_output_sub_buf[sub_idx].size = sf_region.size;
opencl->gpu_output_sub_buf[sub_idx].opencl_mem =
clCreateSubBuffer(opencl->opencl_mem,
CL_MEM_READ_WRITE,
CL_BUFFER_CREATE_TYPE_REGION,
&sf_region, &status);
if (status != CL_SUCCESS)
goto fail;
}
现在,当我映射 gpu_output_sub_buf[0].opencl_mem 和 gpu_output_sub_buf[1].opencl_mem 时,CPU 侧指针之间的区别预计为 alloc_size(假设为 char 指针)。这恰好是英特尔高清显卡的情况。但是 Nvidia 平台提供了不同的结果。
没有 specification-based 原因映射 sub-buffer 应该位于一个地址,该地址是映射主缓冲区的已知偏移量(或映射 sub-buffer 与其对齐)。映射只会创建您可以使用的主机内存范围,然后您取消映射以将其取回设备。它甚至不必每次都在同一个地址。
当然 OpenCL 2.0 SVM 改变了这一切,但你没有说你在使用 SVM,而且 NVIDIA 现在也不支持 OpenCL 2.0。
我创建了一个具有属性 CL_MEM_READ_WRITE 和 CL_MEM_ALLOC_HOST_PTR 的缓冲区。我已将此缓冲区排队到 GPU 内核。 GPU 内核处理给定的输入并填充这些缓冲区。在此过程中 CPU 被等待。我通过使用子缓冲区将缓冲区划分为三个统一的部分来修改此设计。现在GPU填满一个子缓冲区后,CPU就可以开始处理了。这减少了 CPU 等待一个子缓冲区而不是一个完整的帧处理。
我面临的问题是,子缓冲区和缓冲区的映射指针(cpu 侧指针)很奇怪。第一个子缓冲区和缓冲区的映射指针相同。这没关系。但是第二个子缓冲区的映射指针不等于缓冲区的映射指针+第二个子缓冲区的偏移量。我在集成 GPU 型号(Intel HD Graphics 4000)上试过这个。它工作正常。但是当我 运行 在专用显卡设备 (nvidia zotac) 上运行时,我遇到了这个问题。你以前遇到过这样的场景吗。您能否提供一些指示,指出在哪里可以解决此问题。
typedef struct opencl_buffer {
cl_mem opencl_mem;
void *mapped_pointer;
int size;
}opencl_buffer;
// alloc gpu output buffers
opencl->opencl_mem = clCreateBuffer(
opencl->context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
3 * alloc_size, NULL, &status);
if (status != CL_SUCCESS)
goto fail;
// create output sub buffers
for (sub_idx = 0; sub_idx < 3; ++sub_idx) {
cl_buffer_region sf_region;
SubFrameInfo subframe;
sf_region.origin = alloc_size * sub_idx;
sf_region.size = alloc_size;
opencl->gpu_output_sub_buf[sub_idx].size = sf_region.size;
opencl->gpu_output_sub_buf[sub_idx].opencl_mem =
clCreateSubBuffer(opencl->opencl_mem,
CL_MEM_READ_WRITE,
CL_BUFFER_CREATE_TYPE_REGION,
&sf_region, &status);
if (status != CL_SUCCESS)
goto fail;
}
现在,当我映射 gpu_output_sub_buf[0].opencl_mem 和 gpu_output_sub_buf[1].opencl_mem 时,CPU 侧指针之间的区别预计为 alloc_size(假设为 char 指针)。这恰好是英特尔高清显卡的情况。但是 Nvidia 平台提供了不同的结果。
没有 specification-based 原因映射 sub-buffer 应该位于一个地址,该地址是映射主缓冲区的已知偏移量(或映射 sub-buffer 与其对齐)。映射只会创建您可以使用的主机内存范围,然后您取消映射以将其取回设备。它甚至不必每次都在同一个地址。
当然 OpenCL 2.0 SVM 改变了这一切,但你没有说你在使用 SVM,而且 NVIDIA 现在也不支持 OpenCL 2.0。