浅析OpenCL memory object(1)—buffer与image

关于OpenCL内存对象buffer和Image的区别,帮助理解
原文博客地址这里写链接内容

        了解opencl的GPGPU同仁们都必须关注的问题之一就是内存。OCL使用ocl memory object 来存储各种输入或输出数据。ocl memory object 是global memory/constant memory的存储实体。

        ocl memory object可以分为两大类:buffer和image。

        如OCL spec 中所说,buffer具有以下特点:

                 (1).可视为随机访问的线性数组(可读可写),与数组的访问方式相同(Array[idx] = **)

                 (2).可以存储用户自定义的数据结构(自然也支持OCL内建数据类型)

                 (3).在kernel中需要提供buffer的字节参数来确定其大小

        image是一个模式化定制的数据容器,是支持矩阵运算和图像操作的利器。它的结构也与名称一致,具有图像数据的通道个数,通道类型等特征。image具有以下特点:

                (1).内存布局对用户透明(底层实现的硬件相关性大),需要使用内建函数进行读写(read_image, write_image等)

扫描二维码关注公众号,回复: 3336184 查看本文章

                (2).支持的数据类型有限(通道数目+通道的数据类型(单个像素字节数)均有限),不支持自定义的结构体。

                (3).不支持既读又写

                (4).内建函数可以获取图像尺寸,在kernel中无需提供图像尺寸信息

 

        有以上信息可以知道程序员使用那种类型的mem obj来存储数据。显然,如果用户自己定义了如下结构体,那么它只能使用buffer作为存储目标。

        struct 2DPoint

      {

             float  x_pos;

             float  y_pos;

        };

        相应的出现在kernel函数列表内的参数为: __global struct  2DPoint * 2d_PtsArray

        对于图像程序员来说,3通道RGB,4通道RGBA等数据是常用的,可创建为OCL image。如果对一个图像数据有读写的要求,那么不可以简单的使用image来创建它。

        可以有以下解决方案:

               (1)改用buffer来创建图像

               (2)创建一个image备份,将同一图像数据转化为分别可读,可写的两个图像。显然这样将产生复制mem obj的开销(应用相关)

        图像数据往往对间隔访问不敏感,而对于buffer来说,间隔访问可能造成性能下降。笔者的试验表明1280*720p的图像在翻转(flip)操作的时候,对于image来说,naive flip的性能比通过LDS优化的buffer optimal flip性能要高出%40左右(AMD Cypress 5870下)。

       这个数据可能随平台变化,在此的建议是:写出buffer和image两个版本的ocl程序,针对不同平台,灵活的采用性能更优的版本。

       Buffer/Image的传输带宽也有差异。在AMD平台下,可以通过SDK sample中的BufferBandwidth和ImageBandwidth来进行测试。

     

    

   

   

   

     

            </div>

        了解opencl的GPGPU同仁们都必须关注的问题之一就是内存。OCL使用ocl memory object 来存储各种输入或输出数据。ocl memory object 是global memory/constant memory的存储实体。

        ocl memory object可以分为两大类:buffer和image。

        如OCL spec 中所说,buffer具有以下特点:

                 (1).可视为随机访问的线性数组(可读可写),与数组的访问方式相同(Array[idx] = **)

                 (2).可以存储用户自定义的数据结构(自然也支持OCL内建数据类型)

                 (3).在kernel中需要提供buffer的字节参数来确定其大小

        image是一个模式化定制的数据容器,是支持矩阵运算和图像操作的利器。它的结构也与名称一致,具有图像数据的通道个数,通道类型等特征。image具有以下特点:

                (1).内存布局对用户透明(底层实现的硬件相关性大),需要使用内建函数进行读写(read_image, write_image等)

                (2).支持的数据类型有限(通道数目+通道的数据类型(单个像素字节数)均有限),不支持自定义的结构体。

                (3).不支持既读又写

                (4).内建函数可以获取图像尺寸,在kernel中无需提供图像尺寸信息

 

        有以上信息可以知道程序员使用那种类型的mem obj来存储数据。显然,如果用户自己定义了如下结构体,那么它只能使用buffer作为存储目标。

        struct 2DPoint

      {

             float  x_pos;

             float  y_pos;

        };

        相应的出现在kernel函数列表内的参数为: __global struct  2DPoint * 2d_PtsArray

        对于图像程序员来说,3通道RGB,4通道RGBA等数据是常用的,可创建为OCL image。如果对一个图像数据有读写的要求,那么不可以简单的使用image来创建它。

        可以有以下解决方案:

               (1)改用buffer来创建图像

               (2)创建一个image备份,将同一图像数据转化为分别可读,可写的两个图像。显然这样将产生复制mem obj的开销(应用相关)

        图像数据往往对间隔访问不敏感,而对于buffer来说,间隔访问可能造成性能下降。笔者的试验表明1280*720p的图像在翻转(flip)操作的时候,对于image来说,naive flip的性能比通过LDS优化的buffer optimal flip性能要高出%40左右(AMD Cypress 5870下)。

       这个数据可能随平台变化,在此的建议是:写出buffer和image两个版本的ocl程序,针对不同平台,灵活的采用性能更优的版本。

       Buffer/Image的传输带宽也有差异。在AMD平台下,可以通过SDK sample中的BufferBandwidth和ImageBandwidth来进行测试。

     

    

   

   

   

     

            </div>

猜你喜欢

转载自blog.csdn.net/yongtongguan9284/article/details/82491872