zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    《从0开始学架构》——学习笔记(基础篇和高性能篇)
    Oracle的数据并发与一致性详解(下)
    Oracle的数据并发与一致性详解(上)
    关于oracle的缓冲区机制与HDFS中的edit logs的某些关联性的思考
    分布式锁的两种实现方式(基于redis和基于zookeeper)
    hadoop配置文件详解系列(二)-hdfs-site.xml篇
    hadoop配置文件详解系列(一)-core-site.xml篇
    【管理心得之四十六】你呀,少肺
    【管理心得之四十五】你呀,没心
    【管理心得之四十四】独立冲突之外,你做不到
  • 原文地址:https://www.cnblogs.com/willhua/p/9689716.html
Copyright © 2011-2022 走看看