2016-11-10 182 views
1

在Opencl中,緩衝區是通過其從主機應用程序傳送數據的管道。OpenCL - 緩衝區和全局內存之間的區別

cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, 
         void *host_ptr, cl_int *errcode_ret); 

現在,如果我有一個緩衝a_buffer已檢舉爲READ_ONLY,而內核是:

__kernel void two_buffer_double(__global float* a) 
{ 
    int i = get_global_id(0); 
    float b = a[i] * 2; 
} 

我的問題是:是a_buffer全局存儲器或常量內存?我是否應該使用__constant限定符a。 cl_mem_flags(READ_ONLYREAD_WRITE)與內存限定符(globalconstant)之間的連接是什麼?

+0

增加了一些關於「主機端」部分的更多信息。 –

回答

2
__constant 

限定符用於常量內存,有些卡片在紋理高速緩存中獲取並從__global獲得獨立帶寬,但其大小有限。

__global __read_only * float 

手段,OpenCL實現會盡量把它放在高速緩存(或使用一些其他的數據路徑),如果硬件覺得合適,但它是__global因此僅由VRAM大小或數量的限制只是64kB的,而不是(例如)爲__constant。

這些限定符用於設備端優化。

在主機端的優化,你應該用

CL_MEM_READ_ONLY 

提供其作爲標誌緩衝創作。這意味着設備將只讀取它(可能使用一些DMA/pcie訪問/緩存優化),但可以使用enqueuewrite或map unmap操作從主機端(如C#C++代碼的主機,而不是設備)寫入。

__constant 

適用於參數常數定義,不適用於要處理的數據。

如果編寫一個過濾器的代碼,數據可能是__global和濾波器掩模可以是__constant如果不能在__private存儲器(其具有最終帶寬)或__local存儲器(比私人慢)適合所以訪問掩碼字節不降低數據帶寬。

現在回答你的問題:

「?是a_buffer全局存儲器或常量內存」

它是全球性的設備端(內核側),因爲你宣佈它作爲__global,但它可以在主機端(硬件)的任何地方。

編輯:主機端,取決於其它標誌用於其中,例如,USE_HOST_PTR使得從系統RAM它直接可訪問的,並且只有在設備側上的虛擬緩衝器,如果沒有它,並只需CL_MEM_READ_WRITE設備內存將有一個真正的緩衝區和它在RAM中的映射陰影(作爲clenqueueread或clenqueuewrite的子步驟),複製將首先訪問該陰影,然後上傳到GPU。

一個例子設備:英特爾(R)HD(TM)在4GB DDR3L筆記本電腦的圖形400:

Query           value 
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE     65536 bytes 
CL_DEVICE_GLOBAL_MEM_CACHE_SIZE     262144 bytes 
CL_DEVICE_GLOBAL_MEM_SIZE      1636414260 bytes 

CL_DEVICE_GLOBAL_MEM_CACHE_TYPE    CL_READ_WRITE_CACHE 
CL_DEVICE_LOCAL_MEM_SIZE      65536(vs constant, benchmark it) 
CL_DEVICE_LOCAL_MEM_TYPE      CL_LOCAL(so is faster than global) 

無法查詢專用內存大小,但是對於中間段遊戲的AMD卡,它是256KB每個線程組。如果您爲每個組設置64個線程,則每個線程可以使用4KB的寄存器空間,或者由於溢出到全局內存而變慢,因此可以使用4KB的寄存器空間(由於編譯器優化)。