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

OpenCL中的数据并行性表述为一个N维计算域,其中N=1、2或3。N-D域定义了可以并行执行的工作项的总数。下面通过一个简单的例子来了解如何用OpenCL C编写一个数据并行内核,将两个浮点数数组相加。这个代码的串行版本求和时需要通过一个for循环将两个数组中的各个元素相加:

void scalar_add (int n, const float *a, const float *b, float *result)
{int i;for (i = 0; i < n; i++){result[i] = a[i] + b[i];}
}

使用OpenCL C的数据并行代码如下所示。

kernel void scalar_add(global const float *a, global const float *b, global float *result)
{int id = get_global_id(0);result[id] = a[id] + b[id];
}

scalar_add函数声明使用kernel限定符指示这是一个OpenCL C内核。需要说明的是,scalar_add内核只包括计算单个元素求和的代码,也就是内循环。N-D域是设置为n的1维域。对于n个工作项,要为每个工作项分别执行内核来生成数组a和b的和。为此,每个要执行内核的工作项需要知道要对数组a和 b中的哪个元素求和。对于各个工作项来说,这必须是唯一的值,要由N-D域(将内核入队等待执行时指定)得出。get_global_id(0)返回各个工作项的1维全局ID。

图4-1显示了如何使用get_global_id唯一标识执行内核的工作项列表中的一个工作项。

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

OpenCL C基于ISO/IEC 9899:1999 C语言规范(简称为C99),并针对并行性对语言做了一些限制和特定扩展。

OpenCL C还为C99增加了以下特性:
1)矢量数据类型 很多OpenCL设备(如Intel SSE、面向POWER和Cell的AltiVec,以及ARM NEON)都支持矢量指令集。这个矢量指令集在C/C++代码中通过内置函数访问(其中一些可能特定于设备),或者利用设备特定的汇编指令访问。类似于C语言中使用标量类型,在OpenCL C中可以采用同样的方式使用矢量数据类型。基于这一点,开发人员可以更容易地编写矢量代码,因为可以对矢量和标量数据类型使用类似的操作符。这样还便于编写可移植的矢量代码,因为现在的OpenCL编译器会负责将OpenCL C中的矢量操作映射到设备上适当的矢量ISA。基于常规的内存访问以及更好地结合这些内存访问,矢量代码还有助于提高内存带宽。
2)地址空间限定符 诸如GPU等OpenCL设备实现了一个内存层次结构。地址空间限定符用来标识这个层次结构中的一个特定内存区域。
3)对语言的并行性补充 这包括对工作项和工作组的支持,还包括对工作组中工作项之间的同步提供支持。
4)图像 OpenCLC增加了图像和采样器数据类型,还增加了读、写图像的内置函数。
5)庞大的内置函数集合 如数学函数、整数函数、几何函数和关系函数。

标量数据类型

OpenCL C支持的C99标量数据类型如下1。与C不同,OpenCL C指定了整数和浮点数据类型的大小,也就是具体的位数。

bool                       这是一个条件数据类型,可以为true或false值true可以扩展为整数常量1,值false扩展为整数常量0char                       有符号8位整数,2的补值
unsigned char uchar        无符号8位整数
short                      有符号16位整数,2的补值
unsigned short ushort      无符号16位整数
int                        有符号32位整数,2的补值
unsigned int uint          无符号32位整数
long                       有符号64位整数,2的补值
unsigned long ulong        无符号64位整数float                      32位浮点数float数据类型必须符合IEEE 754单精度存储格式double                     64位浮点数double 数据类型必须符合IEEE 754双精度存储格式这是一个可选的格式,只有当设备支持双精度扩展(cl_khr_fp64)时才可用half                       16位浮点数half数据类型必须符合IEEE 754-2008半精度存储格式size_t                     无符号整数类型,这是 sizeof操作符结果的类型如果设备的地址空间为32位,这就是一个32位无符号整数;如果设备的地址空间是64位,这就是个64位无符号整数ptrdiff_t                  有符号整数类型,这是两个指针相减结果的类型如果设备的地址空间为32位,这就是一个32位有符号整数;如果设备的地址空间是64位,这就是一个64位有符号整数intptr_t                   有符号整数类型,它有一个性质,任何指向void的合法指针都可以转换为这个类型,然后还可以再转换回指向void的指针,其结果与原指针比较是相等的uintptr_t                  无符号整数类型,它有一个性质,任何指向void 的合法指针都可以转换为这个类型,然后还可以再转换回指向void的指针,其结果与原指针比较是相等的void                       void类型构成值的一个空集这是一个不完整的类型,而且不能补全

half数据类型

half数据类型必须符合IEEE 754—2008。Half数有一个符号位、5个指数位和10个尾数位。符号、指数和尾数的解释与IEEE754浮点数的相应解释类似。指数偏差为15。half数据类型必须能表示有限标准数、非规格化数、无穷大和NaN(非数字)。half数据类型的非规格化数可能在使用内置函数vstore_half将一个float转换为half时生成,也可能在使用内置函数vload_half将一个half转换为float时生成,这些非规格化数不能刷新为0。

float转换为half时会适当地将尾数舍入为11位精度。Halffloat的转换则是无损的,所有half数都可以准确地表示为float值。

half数据类型只能用来声明指针指向一个包含half值的缓冲区。下面给出几个合法使用half数据类型的例子:

void bar(global half *p)
{....
}void foo(global half *pg, local half *pl)
{global half *ptr;int offset;ptr = pg + offset;bar(ptr);
}

下面是一个非法使用half类型的例子:

half a;
half a[100];half *p;
a = *p; //not allowed. must use vload_half function

可以使用vload_halfvload_halfnvloada_halfn 以及 vstore_halfvstore_halfnvstorea_halfn函数分别完成对half指针的加载和存储。加载(load)函数从内存读取标量或矢量half值,将其转换为一个标量或矢量浮点值。存储(store)函数将一个标量或矢量浮点值作为输入,将它转换为一个half标量或矢量值(采用适当的舍入模式),并把这个half标量或矢量值写入内存。

OpenCL编程指南-4.1OpenCL C编程相关推荐

  1. windows 3.x编程指南_18000 MHz 可编程衰减器

    RC8DAT-8G-95 Mini-Circuits的RC8DAT-8G-95是一款八信道可编程衰减器,广泛应用于信号电平控制应用中,工作频率范围为1 MHz至8GHz.八路通道独立控制,衰减动态范围 ...

  2. python面向对象编程指南([美stevenflott_Python面向对象编程指南 ([美]StevenFLott洛特) 中文_IT教程网...

    资源截图:Python面向对象编程指南 ([美]StevenFLott洛特) 中文 第1部分 用特殊方法实现Python风格的类 . 1 第1章 __init__()方法 5 第2章 与Python无 ...

  3. OpenCL编程指南-1.1OpenCL简介

    什么是OpenCL OpenCL是面向由CPU.GPU和其他处理器组合构成的计算机进行编程的行业标准框架.这些所谓的 "异构系统" 已经成为一类重要的平台,OpenCL是直接满足这 ...

  4. 高质量linux c编程指南,《linux c编程指南》学习手记5

    8.1 流简介 打开:fopen()  标准输入.标准输出.标准错误  关闭:fclose(); 8.2.1 流的打开与关闭 fopen 打开特定的文件 freopen 在一个特定的流上打开一个文件 ...

  5. C++ 模板和 C# 泛型之间的区别(C# 编程指南)

    C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能. 然而,这两者之间存在许多差异. 在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性. 此外,C# 并不 ...

  6. OpenCL Programming Guide - OpenCL 编程指南 - 书中源代码

    OpenCL Programming Guide - OpenCL 编程指南 - 书中源代码 1. Heterogeneous Compute http://www.heterogeneouscomp ...

  7. OpenCL编程指南-1.2OpenCL图形API

    OpenCL与图形 OpenCL的出现是对GPCPU编程的一个响应.人们用GPU处理图形,并且开始使用GPU完成工作中的非图形部分.基于这种趋势,异构计算(已经存在很长时间)与图形发生冲突,因此迫切需 ...

  8. 《树莓派Python编程指南》——2.2 一个Python游戏:猫和老鼠

    本节书摘来自华章计算机<树莓派Python编程指南>一书中的第2章,第2.2节,作者:(美) Alex Bradbury Ben Everard更多章节内容可以访问云栖社区"华章 ...

  9. 《树莓派Python编程指南》—— 1.3 树莓派快速指南

    本节书摘来自华章计算机<树莓派Python编程指南>一书中的第1章,第1.3节,作者:(美) Alex Bradbury Ben Everard更多章节内容可以访问云栖社区"华章 ...

最新文章

  1. python使用numpy中的np.mean函数计算数组的均值、np.var函数计算数据的方差、np.std函数计算数组的标准差
  2. 批量调整word表格根据窗口调整内容
  3. C语言试题二十之利用以下的简单迭代方法求方程cos(x)-x=0的一个实根。
  4. 算法--背包九讲(详细讲解+代码)
  5. matlab中solver函数_Simulink求解器(Solver)相关知识
  6. 项目方案-标书-文档等等编写规范
  7. python执行多个py文件_【经验分享】如何同时运行多个python脚本
  8. 『ORACLE』Oracle GoldenGate搭建(11g)
  9. 【图像去噪】基于matlab GUI均值+中值+高斯低通+多种小波变换图像去噪【含Matlab源码 856期】
  10. [算法]用Python实现十大排序算法
  11. MFC界面开发帮助文档:BCG可视化设计器使用指南
  12. 样点自适应补偿(SAO)技术
  13. 华为路由器配置OSPF实例
  14. 封面文章:寻找技术中国——渴望不再被扼住喉咙!
  15. upupoo启动不了 mysql_【upupoo动态桌面壁纸和mysql-jdbc.jar哪个好用】upupoo动态桌面壁纸和mysql-jdbc.jar对比-ZOL下载...
  16. 借微信更新说说有关版本的那些事儿
  17. h5前端IE浏览器低版本判断及升级提示
  18. 洛谷:P6560 [SBCOI2020] 时光的流逝(博弈、拓扑序列)
  19. 机械手臂c语言如何编程,工业机械手臂程序示教图文教程
  20. 稳中求变,试着提高时间管理能力

热门文章

  1. 微信小程序录音功能实现,并上传录音文件,使用node解析接收
  2. 用Python绘制螺旋文字
  3. C#操作RocketMQ用NewLife.RocketMQ发布消息,消费消息
  4. python二维数组排序_Python排序多维数组
  5. 背景色自动切换html,css3动画之背景颜色的自动切换
  6. 推荐系统[八]算法实践总结V3:重排在快手短视频推荐系统中的应用and手淘信息流多兴趣多目标重排技术
  7. 微信开发者工具-HBuilderX
  8. 如何用C语言写一个服务器和客户端(TCP)
  9. js slice,substr和substring的区别
  10. 千元内哪款蓝牙耳机适合运动用?续航时间长的四款蓝牙耳机测评