2016-01-24 112 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。