OpenCL Introduction - OpenCL 概述

OpenCL 是面向由 CPU、GPU 和其他处理器组合构成的计算机进行编程的行业标准框架,OpenCL 于 2008 年 12 月首次发布。OpenCL 通过公布硬件来提供高度的可移植性,而不是将硬件隐藏在精巧的抽象之下。OpenCL 程序员必须显式地定义平台、上下文,以及在不同设备上调度工作。

1. 异构多核平台

半导体公司竟争的方向不再是原始性能,而是功耗效能。Optimizing power using transformations 中首次提出多核的概念。CPU 中门切换消耗的能量为电容 ( C C C) 乘以电压 ( V V V) 的平方,这些门在 1 秒内切换的次数等于频率。因此一个微处理的功耗计算为 P = C V 2 f P = CV^{2}f P=CV2f。如果将一个频率为 f f f,电压为 V V V 的单核处理器与一个类似的双核处理器 (每个核芯的频率为 f / 2 f / 2 f/2) 进行比较,芯片中的回路数会提高。理论上这会将电容提高 2.2 倍,不过电压会显著减少到 0.6 V 0.6 V 0.6V。在这两种情况下,每秒执行的指令数是一样的,但是双核处理器中的功耗是单核处理器的 0.396 倍。这个基本关系促使微处理器向多核芯片过渡,由多个低功耗核构建计算机中的微处理器,低频率运行的多核在功耗效能上会有显著提高。



上图两种情况下指令执行速率是一样的,不过与单核相比,以一半频率运行的双核功耗会大幅下降。

这些核是一样的 (同构) 还是不一样的 (异构) ?要理解这个趋势,需要考虑专用与通用逻辑的功耗效能。通用处理器本质上必须包括大量功能单元来响应计算需求,芯片也因此成为一个通用处理器。专用于某个特定功能的处理器就不会浪费那么多晶体管,因为它们只包含特定功能所需要的功能单元。这里对一个通用 CPU (Intel Core 2 Quad 处理器 Q6700)、一个 GPU (NVIDIA GTX 280) 和一个相当专用的研究处理器 (Intel 80-Core 万亿级处理器,其内核是一对浮点加乘算术单元) 进行比较。



上图并不是说某一种处理器要优于或劣于其他处理器,重点是只要任务与处理器很好地匹配,芯片越专用,功耗效能就越好。

在一个充分强调最大化每瓦特性能的世界里,完全可以相信系统会越来越依赖于多核,并且在可行的条件下会越来越多地利用专用芯片。异构平台,提供多个指令集和多级并行性,必须充分利用才能最大限度地发挥系统的能力。未来肯定是异构多核平台的天下。

2. 多核世界中的软件

并行硬件通过同时运行多个操作来提高性能,并行硬件要求软件执行时能够作为多个操作流同时运行。软件系统包含多个活动的操作流时,如果这些操作流同时向前推进,则称这个软件系统是并发的,即并发性 (concurrency)。一些操作流 (线程) 等待某些资源时,允许另外一些操作流继续推进,这样能够最大化资源的利用率。通过并发,与系统交互的用户还会有一种错觉,认为与系统的交互是连续的,而且几乎是即时的。

当并发软件在拥有多个处理单元的计算机上运行时,线程实际上可以同时运行,从而可以实现并行计算。硬件支持的并发性就是并行性。

并行程序设计的关键是一个高层抽象或模型 (model),使并行程序设计问题更可管理。两个并行程序设计模型:任务并行 (task parallelism) 和数据并行 (data parallelism)。OpenCL 同时支持数据并行和任务并行两种模型。

在数据并行程序设计模型中,并行性表述为将相同的指令流 (一个任务) 并发地应用到各个数据元素,并行性体现在数据中。使用数据并行程序设计模型,通过将任务应用到矢量中的每一个元素来并行地更新矢量,生成一个新的结果矢量。

在任务并行程序设计模型中,问题分解为可以并发运行 的任务,然后再映射到一个并行计算机的处理单元 (Processing Element, PE) 来执行。如果任务是完全独立的,使用这个模型最为容易,不过这个模型也可以用于共享数据的任务。如果要利用一组任务来计算,只有当最后一个任务完成时这个计算才算完成。负载平衡 (load balancing) 要让每个 PE 计算所花费的时间相同。


程序员需要把软件想象成一组模块,分别实现问题的不同部分,这些模块显式地绑定到异构平台中的组件。

通用 GPU (General-Purpose GPU,GPGPU) 编程,图形以外的算法会修改为适合于 GPU 处理。CPU 完成计算并管理 I/O,不过所有实质性的计算都分摊给 GPU。异构平台会被忽略,而把重点放在系统中的一个组件 GPU 上。OpenCL 不建议釆用这种方法,有效的程序就应当使用所有这些设备,这也是我们对异构平台设计编程环境的期望。异构编程语言则是公布异构性,与增加抽象的趋势背道而驰。

3. OpenCL 框架的组成

  • OpenCL 平台 API:平台 API 定义了宿主机程序发现 OpenCL 设备所用的函数,以及为 OpenCL 应用创建上下文的函数。
  • OpenCL 运行时 API:运行时 API 管理上下文来创建命令队列以及运行时发生的其他操作,将命令提交到命令队列的函数就来自 OpenCL 运行时 API。
  • OpenCL 编程语言:用来编写内核代码的编程语言。它基于 ISO C99 标准的一个扩展子集,通常称为 OpenCL C 编程语言。

3.1 平台 API

平台 (platform) 表示宿主机、OpenCL 设备和 OpenCL 框架的组合。一个异构计算机上可以同时存在多个 OpenCL 平台。OpenCL 程序员为宿主机程序编写代码时,调用平台 API 的函数为 OpenCL 计算定义上下文。

3.2 运行时 API

平台 API 中的函数为 OpenCL 应用定义上下文。运行时 API 则强调使用这个上下文满足应用需求的函数。运行时 API 的第一个任务是建立命令队列,可以将命令队列关联到一个设备,不过一个上下文中可以同时有多个活动的命令队列。

有了命令队列,就可以使用运行时 API 来定义内存对象和管理内存对象所需要的所有其他对象。为了支持垃圾回收,OpenCL 会跟踪多少个内核实例使用这些对象 (持有一个内存对象),以及内核何时用完一个内存对象 (即释放一个内存对象)。

运行时 API 管理的另一个任务是创建构建动态库所用的程序对象,内核就由这些动态库定义。程序对象、编译程序对象的编译器以及内核定义都在运行时层处理。与命令队列交互的命令都由运行时层的函数发出。管理数据共享和对内核执行施加约束的同步点也由运行时 API 处理。

3.3 内核编程语言

OpenCL 中的内核编程语言称为 OpenCL C 编程语言,它由 ISO C99 语言派生而来。在 OpenCL 中,要对支持可移植性特别当心。这要求我们标准化不同类的 OpenCL 设备之间的最小公共子集。由于 C99 中有些特性只有 CPU 能够支持,所以去掉了 C99 的一些语言特性,删除的主要语言特性包括:

  • 递归函数。
  • 函数指针。
  • 位域。

OpenCL 编程语言中不支持的标准头文件很多,包括 stdio.hstdlib.h

我们将 OpenCL C 编程语言限制为只满足用于 OpenCL 的关键 OpenCL 设备的需求。出于同样的原因,促使我们扩展语言以及以下方面:

  • 矢量类型和这些类型实例上的操作。
  • 地址空间限定符,支持 OpenCL 对多个地址空间的控制。
  • 一组丰富的内置函数,支持 OpenCL 应用中通常需要的功能。
  • 全局和局部内存中处理无符号整数和单精度标量变量的原子函数。

大多数编程语言忽略浮点算术系统的特定细节。它们只是从硬件导入算术系统,从而完全避开这个问题。由于所有主流 CPU 都支持 IEEE 754 和 IEEE 854 标准,所以这个策略是可行的。实际上,通过集中研究这些浮点标准,硬件开发商在为语言开发商解决浮点定义的有关问题。在异构世界中,如果脱离 CPU,那么对浮点算术运算的支持会有更多的选择。通过与硬件开发商的紧密合作,我们希望大力推动他们完善对 IEEE 浮点标准的支持。同时不希望对这些开发商过于苛刻,所以赋予他们一定的灵活性可以避开 IEEE 标准中一些不常使用但实现很困难的特性。

从高层可以总结为 OpenCL 需要以下特性:

  • 对 IEEE 754 格式的全面支持。双精度是可选的,不过如果提供双精度,也必须符合 IEEE 754 格式。
  • 支持默认的 IEEE 754 舍入模式,即舍入为最近整数。其他舍入模式尽管值得推荐,但它们是可选的。
  • 尽管 IEEE 规范要求动态改变舍入模式,但 OpenCL 中的舍入模式是静态设置的。
  • 必须支持特殊值 INF (无穷大) 和 NaN (非数字),不过不要求提示 NaN (通常反映并发系统中的问题)。
  • 非规格化数 (小于 1 的数乘以所支持的最大负指数) 可以化简为 0。

OpenCL 规范并不仅限于 IEEE 标准。在 OpenCL 规范中,还有一些表格详尽地定义了数学函数中允许的相对误差。

4. OpenCL 语言基本工作流

OpenCL 是编写异构平台上执行并行程序的一个行业标准。OpenCL 平台模型定义了一个抽象,适用于各种异构系统。OpenCL 执行模型描述了各类计算以及它们如何映射到平台模型。OpenCL 还包含编程模型和内存模型。

在 OpenCL 框架中的基本工作流,OpenCL 的组成以及一个 OpenCL 应用执行期间在宿主机上发生的动作。


首先是一个定义上下文的宿主机程序,上下文包含两个 OpenCL 设备、一个 CPU 和一个 GPU。接下来定义了命令队列。这里有两个队列,一个是面向 GPU 的有序命令队列,另一个是面向 CPU 的乱序命令队列。然后宿主机程序定义一个程序对象,这个程序对象编译后将为两个 OpenCL 设备 (CPU 和 GPU) 生成内核。接下来宿主机程序定义程序所需的内存对象,并把它们映射到内核的参数。最后,宿主机程序将命令放入命令队列来执行这些内核。

5. OpenCL 与图形

OpenCL 的出现是对 GPGPU 编程的一个响应。图像内存对象是包含纹理、帧缓冲区或图像的 1 维、2 维或 3 维对象。实现可以支持各种图像格式,不过至少必须支持标准 RGBA 格式。图像对象使用 OpenCL 中定义的一组函数来管理。OpenCL 还定义了采样器对象,允许程序员采样和过滤图像。这些特性已经集成到 OpenCL API 的一组核心图像管理函数中。

在 OpenCL 标准的附录中将它们定义为一组可选的扩展:

  • 从 OpenGL 上下文创建一个 OpenCL 上下文。
  • 在 OpenCL,OpenGL 和 OpenGL ES 之间共享内存对象。
  • 从 OpenGL 同步对象创建 OpenCL 事件对象。
  • 与 Direct3D 10 共享内存对象。

6. 嵌入式简档

OpenCL 程序可以满足各类硬件平台的需要,对于某些特性,嵌入式处理器可能无法满足标准中的需求。我们有两个选择:一种是取捷径,把问题交给各个开发商,让他们决定如何放宽 OpenCL 规范来满足他们的需要;另一种做法是自己动手,明确定义如何为嵌入式处理器修改 OpenCL。OpenCL 选择定义了如何修改 OpenCL 规范来适应嵌入式处理器的需要。

我们放宽了浮点数标准和一些较大的数据类型,因为这些在嵌入式市场上较少用到。原子函数不是必要的,内置数学函数的相对误差也已放宽。框架中不同组件属性的最小参数 (如私有内存区域所需要的最小大小) 有所缩减,以适应嵌入式市场中使用的更严苛的内存大小约束。在很多情况下,面向嵌入式处理器的 OpenCL 都很接近于完整的 OpenCL 定义。

References

(美) Aaftab Munshi, (美) Benedict R. Gaster, (美) Timothy G. Mattson, (美) James Fung, (美) Dan Ginsburg 著, 苏金国, 李璜, 杨健康 译. OpenCL 编程指南. 机械工业出版社, 2012.
https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
http://www.heterogeneouscompute.org/?page_id=5
http://www.heterogeneouscompute.org/?page_id=7
https://github.com/bgaster/opencl-book-samples
https://www.nersc.gov/assets/pubs_presos/MattsonTutorialSC14.pdf

OpenCL Introduction - OpenCL 概述相关推荐

  1. Boost:使用OpenCL和OpenCL计算直方图的代码示例

    Boost:使用OpenCL和OpenCL计算直方图的代码示例 实现功能 C++实现代码 实现功能 ,Boost的compute模块使用OpenCL和OpenCL计算直方图的代码示例 C++实现代码 ...

  2. OpenCL简介-----OpenCL学习(一)

    OpenCL (Open Computing Language,开放计算机语言)是一个为异构平台编写程序的框架,此异构平台可由CPU,GPU或其他类型的处理器组成.OpenCL由一门用于编写kerne ...

  3. 计算机缺少opencl.dll,opencl.dll损坏,如何修复

    因为蓝牙经常丢失而且断连,我使用了sfc /scannow 命令进行自动修复,显示 Windows 资源保护找到了损坏文件但无法修复 然后我使用 dism /online /cleanup-image ...

  4. 测试opencl软件,OpenCL应用测试

    ◆ OpenCL应用测试 GUIMiner挖矿测试 GUIMiner是一个免费的比特币挖矿软件,让你用电脑的CPU或显卡的GPU来挖取比特币,支持多个比特币服务器,支持多个矿工,测试使用OpenCL挖 ...

  5. 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块

    参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL模块所支持的函数 ...

  6. AMD OpenCL 大学课程

    AMD OpenCL大学课程是非常好的入门级OpenCL教程,通过看教程中的PPT,我们能够很快的了解OpenCL机制以及编程方法.下载地址:http://developer.amd.com/zone ...

  7. Intro OpenCL Tutorial

    Benedict R. Gaster, AMD Architect, OpenCL™ OpenCL™ is a young technology, and, while a specification ...

  8. 使用OpenCV的OpenCL(ocl)模块

    Preface 参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL ...

  9. OpenCL 通用编程与优化(14)

    OpenCL 通用编程与优化(14) 9. Adreno GPU中的OpenCL扩展 9.1 OS依赖性供应商扩展 9.1.1 性能提示 (cl_qcom_perf_hint) 9.1.2 上下文创建 ...

最新文章

  1. c语言-01背包问题
  2. 夜间奇异规范:夜间高效自监督单目深度估计(ICCV 2021)
  3. 【原】使用Json作为Python和C#混合编程时对象转换的中间文件
  4. Mac-远程连接Mac
  5. 指针 是否相同_c专题之指针---野指针和空指针解析
  6. 两种通过代码访问SalesOrder header text内容的办法
  7. vue双向数据绑定的原理
  8. 【专升本计算机】专升本计算机期末考试复习题(C卷附答案)
  9. 文本框宽度自动适应文本宽度
  10. 轻触开源(一)-Java泛型Type类型的应用和实践
  11. sqlserver 更新 datetime 数据_SqlServer 关于 datetime 的更新引发的思考
  12. 如何从基础到深入了解java构造器
  13. 逐像元地表反射率计算(GF4)
  14. Java视频教程下载地址汇总
  15. unicode转gbk python_使用python实现GBK转unicode码查询表
  16. t480 拆触摸板_来自NBC的ThinkPad T480评测:平衡的高端商务笔记本
  17. mysql一个汉字是几个字节_mysql里一个中文汉字占多少字节数?
  18. idea禁用双击shift、double shift 快捷键
  19. java中的set_java中的set是什么意思
  20. 微信公众平台接口程序语音天气

热门文章

  1. Linux打开和关闭防火墙指令
  2. allegro17.2 精确画圆形边框
  3. 钢结构建筑软件:Advance Steel 2024 激活版
  4. 大数据应用项目创新大赛_创新创业大赛聚焦大数据应用 15个项目进入决赛
  5. CentOS6修改开机启动菜单背景图片
  6. 训练数据的归一化处理
  7. python学习turtle(移动和绘制)
  8. APP Invertor 制作BLE蓝牙APP 控制esp32蓝牙小车
  9. 医院弱电工程辨别光缆八步骤
  10. 【Vue】vuex-五个核心