buffer,sub-buffer和image對比
相同點:都是OCL memory對象
維度 | 特性關鍵詞 | |
---|---|---|
buffer | 一維 | array of bytes |
sub-buffer | 一維 | views into buffer |
image | 二維或者三維 | 讀寫操作、可選的format、sampler及clamp |
關於buffer的釋放問題
在OpenCL中,對於cl_mem
對象都是采用reference-counted的模式來控制對相應資源的釋放的。OpenCL中增加某個cl_mem
的方法為 cl_int clRetainMemObject ( cl_mem memobj)
,而clCreateBuffer, clCreateSubBuffer, clCreateImage2D, and clCreateImage3D都會執行一個 implicit retain。clCreateSubBuffer also performs an implicit retain on the memory object used to create the sub-buffer or image object. 所以,如果一個cl_men對象創建了多個sub-buffer,那么應該對每個sub-buffer都進行clRelaseMemObject
. 降低引用計數的方法為cl_int clReleaseMemObject ( cl_mem memobj)
. 當一個cl_mem
的引用計數變為0,且相關的命令也已經執行完畢,那么OCL就會釋放相關資源。
另外,clSetKernelArg並不會retain相關的cl_mem。
查詢cl_mem對象的相關信息
可以使用clGetMemObjectInfo
查詢到cl_mem
對象的各種相關信息。如下的代碼查詢cl_mem
對象是何種類型:
cl_int errNum;
cl_mem memory;
cl_mem_object_type type;
// initialize memory object and so on
errNum = clGetMemObjectInfo(
memory,
CL_MEM_TYPE,
sizeof(cl_mem_object_type),
&type,
NULL);
switch(type)
{
case CL_MEM_OBJECT_BUFFER:
{
// handle case when object is buffer or sub-buffer
break;
}
case CL_MEM_OBJECT_IMAGE2D:
case CL_MEM_OBJECT_IMAGE3D:
{
// handle case when object is a 2D or 3D image
break;
}
default
// something very bad has happened
break;
}
buffer的讀寫
OpenCL中,host可以使用command來執行對buffer的讀寫。值得一提的是,在創建buffer的時候,比如使用clCreateBuffer
,使用合適的參數,比如CLK_MEM_COPY_HOST
,也可以實現對buffer資源的寫入操作。但是,這種做法起碼有三個明顯的局限性:
- 只能在創建buffer的時候執行寫入,而無法對已經存在的
cl_mem
對象執行寫入 - 只能寫,而不能讀
- 只能寫全部的數據,而不能只寫部分片段的數據
而OCL提供的相關command則可以十分自由的進行各種操作。
- clEnqueueWriteBuffer:把host的內容寫入的buffer region
- clEnqueueReadBuffer:把buffer的內容復制到host內存中
- clEnqueueReadBufferRect:把一個二維或者三維的buffer的部分區域數據復制到host內存
- clEnqueueWriteBufferRect:把host上的數據寫入到二維或者三維buffer的局部區域
- clEnqueueCopyBuffer:從一個buffer拷貝數據到另一個buffer,適用於一維的
- clEnqueueCopyBufferRect:從一個buffer拷貝片段數據到另一個buffer片段,適用於二維或者三維的
map buffer and sub-buffer
mapping一個buffer或者sub-buffer可以得到一個host指針,這個指針可以直接在host上使用,比如作為參數傳給其他函數,但這些函數不會感知到這些內存實際是由OCL管理並利用的。
map使用clEnqueueMapBuffer
,使用完之后需要unmap,使用clEnqueueUnmapMemObject
.