OpenCL的buffer以及sub-buffer


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資源的寫入操作。但是,這種做法起碼有三個明顯的局限性:

  1. 只能在創建buffer的時候執行寫入,而無法對已經存在的cl_mem對象執行寫入
  2. 只能寫,而不能讀
  3. 只能寫全部的數據,而不能只寫部分片段的數據

而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.

參考:OpenCL Programming Guide


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM