OpenCL的内存对象被分为两类,而这两类内存对象的具体位置、布局以及格式由参数来定义。这两类内存对象是buffer和image。

buffer内存对象

以传统CPU的意义看,buffer对象是一维数组,类似C程序中的malloc函数。buffer对象支持的数据类型可以是任意标题、向量以及用户自定义的数据类型。buffer对象中存储 的数据是连续的,这就使OpenCL kernel可以用C程序员熟悉的指针随机访问方式来读取它们。

image内存对象

image对象采用的是不同的方法。因为GPU是为处理图像任务而设计的,所以对图像数据的访问进行了深入优化。image与buffer主要区别:

  • 对设备代码是不可见的,不能通过指针直接访问。

  • 多维结构。

  • 仅限于图像数据相关数据类型,而不能自由实现任意数据类型。

为优化图像数据访存而进行的数据布局格式的变换,使得通过定义指针来访问数据非常困难。因为不同内存对象之间的位置关系对开发者来说是不可见的。最后的结果是图像数据结构不仅对开发人员不可见,对kernel代码来说也是完全不可见。只能通过专用函数来访问。

在处理图像数据时。用image内存较buffer内存更有效率。这节我们学习如何用image内存处理数据。

这节依然会用到读取和存储图像数据的函数,打开CL文件函数。这些以往章节都有,从这节起就不再复制上来了(节省大家阅读时间)。

一、使用Image内存处理图像数据要掌握以下几个概念。

1.主机上的图像对像是cl_mem,使用clCreateImage2D或clCreateImage3D来创建。

2.主机上的采样器。cl_sampler,它规定了内存数据的存储格式。他的格式如下:

code blocks结构化程序设计(用Codeblocks进行OpenCL编程8)(1)

3.内核图像对像:image2d_t和image3d_t,指明像素的坐标。

4.内核图像读取函数。

内核图像数据读取函数有read_imagex和write_imagex。x可取i,f,ui等值。表示整型,浮点和无符号整型数据。

5.内核图像信息函数。

get_image_width:获取图像宽度

get_image_height:获取图像高度

get_image_depth:获取图像深度

get_image_dim:获取图像长、高和深度

以上只是简录一些常用的函数。下面我们看一个例子。读取一张JPG,然后不做任何处理再保存成PNG,我们主要学习如何使用Image内存。

二、main.cpp源码

code blocks结构化程序设计(用Codeblocks进行OpenCL编程8)(2)

code blocks结构化程序设计(用Codeblocks进行OpenCL编程8)(3)

code blocks结构化程序设计(用Codeblocks进行OpenCL编程8)(4)

三、save.cl源文件

code blocks结构化程序设计(用Codeblocks进行OpenCL编程8)(5)

,