第四章 OpenCL C编程

OpenCL C编程语言用来创建爱你描述数据并行内核和任务的程序,这些内核和任务可以在一个或多个异构设备上执行,如CPU、GPU和另外一些成为加速器的处理器。OpenCL程序类似于一个动态库,OpenCL内核则类似于动态库的一个导出函数。应用程序可以直接从代码调用由动态库导出的函数。不过,应用程序不能直接调用OpenCL内核,只能讲内核的执行放在一个为设备创建的命令队列中排队。内核与宿主机CPU上运行的应用代码异步执行。

4.1 使用内核OpenCL C编写数据并行内核

4.2 标量数据类型

4.3 矢量数据类型

OpenCL还增加了对矢量数据类型的支持。矢量数据类型如下定义,首先是类型名,具体包括char、unchar等,后面是一个字面值n来定义矢量中的元素个数。对于所有矢量数据类型,支持的n值包括2、3、4、8和16。如类型charn表示n个8位有符号整数值的矢量。声明一个标量或矢量数据类型的变量要按照所用数据类型的大小(字节数)对齐。

4.3.2 矢量分量

在1~4个分量(即元素)的矢量数据类型中,其分量可以表示为<vector>.xyzw

float2 pos;
pos.x = 1.0f;
pos.y = 2.0f;
pos.z = 3.0f;   //error  

矢量数据类型可以使用.lo(或.odd)和hi(或.even)后缀来得到较小的矢量类型,或者把较小的矢量类型结合为一个较大的矢量类型。还可以使用多层.lo和.hi后缀,直至指向一个标量类型。.lo后缀指示一个给定矢量的低半部分,hi后缀指示给定矢量的高半部分。

float4 vf;
float2 low = vf.lo;    //return vf.xy
float2 high = vf.hi;   //return vf.zw

4.4 其它数据类型  

OpenCL C支持的其它数据类型如表所示

类型 描述
image2d_t 2D图像类型
image3d_t 3D图像类型
sampler_t 图像采样器类型
event_t 事件类型

 

 

 

 

对于图像和采样器类型的使用,存在一些限制:

  • 只有当设备支持图像时才能定义图像和采样器类型;
  • 不能声明为数组;
  • 不能在结构体中声明
  • 变量不能声明为image2d_t,image3d_t,sampler_t类型的指针。

4.5 衍生类型

4.6隐式类型转换

不允许内置矢量数据类型之间进行隐式转换。矢量之间的强制类型转换时不合法的。

4.11 限定符

OpenCL支持5类限定符:函数限定符、内核属性限定符、地址空间限定符、访问限定符和类型限定符。

4.11 函数限定符

OpenCL增加了kernel(或_kernel)函数限定符。这个限定符用来指定程序源代码中的函数是一个内核函数。

内核函数适用于以下规则:

  • 返回类型必须是void。如果返回类型不是void,会导致一个编译错误。
  • 从宿主机执行内核的命令可以入队,从而可以在设备上执行这个函数。
  • 如果从一个内核调用,则函数表现为一个常规的函数。唯一的限定是,如果一个内核函数中用local限定符声明的变量,则不能从另一个内核函数调用该函数。

4.11.3 地址空间限定符

执行一个内核的工作项可以访问4个内存区域。这些区域可以指定为类型限定符。类型限定符可以是global(_global)、local、constant或private。

如果一个对象的类型由一个地址空间名限定,那么这个对象就在指定的地址空间中分配;如果地址空间名为指定,那么对象就在通用地址空间中分配。通用地址空间名为private.

如果内核函数的参数声明为某个类型的指针,那么这样的参数只能指向以下地址空间:global、local或constant。如果没有为这种参数指定地址空间名,就会导致一个编译错误。这个限制不适用于程序中的非内核函数。

全局地址空间

这个地址空间用来指示从全局内存区域分配的内存对象。这个内存区域允许读/写访问一个内核的所有工作组中的所有工作项。这个地址空间由global限定符标识。

全局地址限定符不能用于图像类型。

全局地址空间的指针可以作为函数的参数和函数内部声明的变量。函数中声明的变量不能再全局地址空间中分配。

void my_func(global float4 *vA, global float4 *vB) {
        global float4 *p;    //legal
        global float4 a;      //illegal
}      

常量地址空间

这个地址空间名用来描述全局内存中分配的一些变量,这些变量在内核中作为只读变量访问。这个内存区允许只读访问执行一个内核的所有工作组中的所有工作项。这个地址空间由constant限定符标识。

图像类型不能在常量地址空间中分配。

常量地址空间的指针可以作为函数(包括内核函数)的参数和函数内声明的变量。

内核函数作用域中的变量可以在constant地址空间分配。程序作用域中的变量只能在constant地址空间分配。

局部地址空间

这个地址空间名用来描述需要在局部内存中分配的变量,这些变量由执行内核的一个工作组(而非多个工作组)的所有工作项共享。这个内存区域允许读/写访问一个工作组中的所有工作项。局部地址空间由local限定符标识。

局部地址空间的指针可以作为函数(包括内核函数)的参数和函数内部变量的声明。内核函数中声明的变量可以在局部地址空间中分配,但是有一些限制:

  • 这些变量声明必须出现在内核函数作用域
  • 这些变量不能初始化

局部地址空间中的变量如果作为指针参数传递,或者在一个函数内部声明,那么仅在这个内核的工作组的声明周期内存在。

私有地址空间

这个地址空间名用来描述对一个工作项私有的变量,这些变量不能在一个工作组中的工作项之间或者工作组共享。私有地址空间由private限定符标识。

4.11.4 访问限定符

访问限定符可以用图像类型的参数指定。这些限定符指定图像是否为只读(read_only或_read_only)或只写(write_only或_write_only)图像。

原文地址:https://www.cnblogs.com/tcsong24/p/7645925.html