OpenCL子缓冲区主机指针

时间:2016-01-24 14:17:26

标签: opencl

我创建了一个具有CL_MEM_READ_WRITE和CL_MEM_ALLOC_HOST_PTR属性的缓冲区。我已将此缓冲区排入GPU内核。 GPU内核处理给定的输入并填充这些缓冲区。在此过程中,CPU会等待。我通过使用子缓冲区将缓冲区分成三个统一的部分来修改此设计。现在GPU填充一个子缓冲区后,CPU就可以开始处理了。这减少了CPU等待一个子缓冲区而不是一个全帧处理。

我面临的问题是,子缓冲区和缓冲区的映射指针(cpu侧指针)很奇怪。第一个子缓冲区和缓冲区的映射指针是相同的。这没关系。但是第二个子缓冲区的映射指针不等于第二个子缓冲区的缓冲区+偏移量的映射指针。我在集成GPU模型(英特尔高清显卡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平台正在提供不同的结果。

1 个答案:

答案 0 :(得分:2)

没有基于规范的原因,映射的子缓冲区应该位于与映射的主缓冲区(或与其对齐的映射的子缓冲区)的已知偏移量的地址处。映射仅创建可以使用的一系列主机内存,然后取消映射以将其恢复到设备上。它不必每次都在同一个地址。

当然,OpenCL 2.0 SVM会改变这一切,但你并没有说你正在使用SVM,而且NVIDIA今天也不支持OpenCL 2.0。