2016-01-24 69 views
1

我创建了一个属性为CL_MEM_READ_WRITE和CL_MEM_ALLOC_HOST_PTR的缓冲区。我已经将这个缓冲区排入GPU内核。 GPU内核处理给定的输入并填充这些缓冲区。在这个过程中,CPU等待。我通过使用子缓冲区将缓冲区划分为三个统一部分来修改了这种设计。现在GPU填充一个子缓冲区后,CPU可以开始处理。这减少了CPU等待到一个子缓冲区,而不是一个完整的帧处理。OpenCL子缓冲区主机指针

我面临的问题是,子缓冲区和缓冲区的映射指针(CPU端指针)很奇怪。第一个子缓冲区和缓冲区的映射指针是相同的。这没关系。但第二个子缓冲区的映射指针不等于第二个子缓冲区的缓冲区+偏移量的映射指针。我在集成GPU模型(英特尔HD图形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(假设字符指针)。英特尔高清显卡就是这种情况。但是Nvidia平台提供了不同的结果。

+0

你是什么意思由_map指针的第二个子缓冲区_?你能否给你的问题添加一些代码来显示调用'clCreateBuffer'(C API)或构建'cl :: Buffer'(C++ API)? –

+1

您添加的代码段错过了“mapped_pointer”的分配。 –

回答

2

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

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