《OpenCL实战》一1.2 为什么是OpenCL

简介: 你可能听说过这样的表述,OpenCL指的是一门独立的语言,但其实,这种表述其实并不准确。OpenCL标准只是在C和C++的基础之上,扩展定义了一些数据类型,数据结构以及函数罢了。尽管开发人员已经针对Java和Python设计了一系列的OpenCL接口库,但标准中只要求OpenCL框架提供C和C++编写的API。

本节书摘来异步社区《OpenCL实战》一书中的第1章,第1.2节,作者: 【美】Matthew Scarpino 译者: 陈睿 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.2 为什么是OpenCL

你可能听说过这样的表述,OpenCL指的是一门独立的语言,但其实,这种表述其实并不准确。OpenCL标准只是在C和C++的基础之上,扩展定义了一些数据类型,数据结构以及函数罢了。尽管开发人员已经针对Java和Python设计了一系列的OpenCL接口库,但标准中只要求OpenCL框架提供C和C++编写的API。

OpenCL和多核计算史上的重大事件如下:

2001-IBM发布POWER4,第一块多核处理器;

2005-第一批针对桌面电脑的多核处理器发布:AMD的Athlon64 X2和Intel的Pentium D;

2008年6月-OpenCL工作组形成,加入Khronos Group大家庭;

2008年12月-OpenCL工作组发布了OpenCL v1.0的规格标准;

2009年4月-Nvidia发布了针对Nvidia显卡的OpenCL SDK;

2009年8月–ATI(现在的AMD)发布了针对ATI显卡的OpenCL SDK。Apple在Mac OS 10.6(雪豹版)中加入了对OpenCL的支持;

2010年6月-OpenCL工作组发布了OpenCL v1.1的规格标准。

这里有个很棘手的问题:有什么是你能靠OpenCL完成,而一般的C和C++编程却束手无策?而这正是我要用整本书来完整解释、回答的问题,但是首先,我们还需要考察OpenCL的三个主要优势:可移植性,标准化的向量处理,以及并行编程。

1.2.1 可移植性

Java是世界上最为著名的编程语言之一,而它的成功很大程度上应当归功于它的那句格言:“一次编写,各处运行(Write once,run everywhere)[2]”。有了Java,你并不需要针对不同的操作系统重写自己的代码。只要操作系统兼容支持JVM(Java Virtual Machine,Java虚拟机),你的代码就能运行。

OpenCL秉承的是同样的理念,但那句格言还得改改才更适用,“一次编写,各设备上运行(Write once, run on anything)”。每个芯片厂商不仅提供兼容OpenCL的硬件,还提供开发工具编译OpenCL代码,支持其在硬件上的运行。换言之,你只需要一次编写OpenCL例程,便可以保证其在兼容芯片(多核处理器或是显卡)上的编译、运行。这便是相对于传统的高性能计算的巨大优势,你并不需要针对特定产商的硬件,而去学习它们的专用编程语言。

而OpenCL所带来的好处并不仅仅只是能够在任何兼容硬件上运行。OpenCL应用程序可以针对不同的设备完成一次编译,这些设备甚至都不需要有相同的体系结构,或是来自同一个厂商。只要他们的设备能够兼容OpenCL,编写的函数便能运行。而这是以往的C/C++编程所无法达到的,它们所编写的程序只能是在特定的编译目标上运行。

这里有一个实例。设想你有一块来自AMD的多核处理器芯片,一块来自Nvidia的显卡以及一块来自IBM的通过PCI连接的加速器。一般而言,你根本不可能针对这三个不同的系统进行一次性的程序编写,而它们所要求的编译器和链接器也是各不相同。但是OpenCL程序所编写的可执行程序却可以在三种不同的硬件上运行。换言之,现在可以靠同样的程序在不同平台的硬件上完成相同的任务。如果你还有更多的兼容设备需要考虑,只需要重新编译程序即可,而不是重写所有的代码。

1.2.2 标准化的向量处理

标准化的向量处理也是OpenCL的一大优势,但在我解释原因之前,还是需要对所讨论的问题稍加定义。这里的术语向量将贯穿本书始终,而它的表述也可分为如下三种(尽管三种表述本质上都差不多):

  • 物理或几何向量—一个带有幅值和方向的物理量。在物理学中,它经常被用来刻划作用力,速度,热传导等物理量。而在图像处理中,向量则被用来表示方向。
  • 数学向量—一个有序的由元素组成的一维集合。这区别于由元素组成的二维集合,矩阵。
  • 计算向量—一个包含多个相同数据类型元素的数据结构。在向量运算中,对其中的每个元素(也叫向量分量(component))的运算处理也都同时进行。

最后一种表述对OpenCL而言非常的重要,而高性能处理器也正是要完成这一操作。如果你有听说过超标量处理器或是矢量处理器的话,这也就是我们所讨论的设备类型。基本上所有的现代处理器都具备处理向量运算的能力,但ANSI C/C++并没有定义任何基本的向量数据类型。这听起来很奇怪,但确实是个显而易见的问题:向量指令基本上都是针对向量来的。Intel处理器使用的是SSE指令扩展,Nvidia芯片需要PTX指令集,而IBM的芯片则是依靠AaltiVec指令集来执行向量运算。这些指令集都没有任何共通之处[3]。

但是有了OpenCL,你便可以实现“一次编写,各设备上运行”的想法。具体到不同平台的应用程序,Nvidia的OpenCL编译器会输出PTX指令的程序,而IBM的OpenCL编译器会输出AltiVec指令的程序。显然,如果你是要面向多个硬件平台编写高性能的应用程序,OpenCL绝对会节省大量的时间。在第4章中,我们将讨论OpenCL的矢量数据类型,而在第5章中,我们将看到具体有那些函数来负责向量操作。

1.2.3 并行编程

如果你有过大规模的应用程序的编程经验,你肯定接触过并发(concurrency)[4]的概念——顺序代码通过任务调度在进程(或线程)间实现资源分享,并行执行。OpenCL包含了并发的特点,但更重要的是它带来了并行编程(parallel programming)的可能。并行编程就是将不同的运算任务分配给多个不同的处理单元,同时并行执行。

在OpenCL之中,这些任务被称为内核。而内核是针对一个或多个兼容OpenCL的设备而特别编写的函数,并通过主机应用程序发送到相应的一个或多个设备上。主机应用程序就是一个在我们称为主机的用户开发系统上运行的C/C++应用程序。主机既可以选择将内核程序发送到计算机显卡上的GPU中运行,也可以选择当前的CPU作为执行目标。

主机应用程序通过名为上下文(context)的容器来管理所连接的设备。图1.1所示的是主机与内核及设备之间的相互关系。

主机必须要从一个名为程序(program)的内核容器中选择函数,才能创建出内核程序;然后,它再向内核函数中调入相应的参数数据,并发送到名为指令序列的数据结构中。指令序列是主机实现对设备控制的一种机制,而当内核入列时,设备便会执行相应的函数。

OpenCL应用程序可以配置不同的设备来完成不同的任务,每个任务都是对不同的数据进行运算处理。换言之,OpenCL提供的是任务并行的机制。这也是相比于其他并行编程工具集的重要优势,其他的开发工具只允许数据并行的处理机制。在数据并行的系统中,每个设备都收到相同的指令,但处理的是整个数据集的不同部分。

图1.1所示的是OpenCL在设备间完成任务并行处理的整个过程;这张图并没有给出设备内部的运行机制。大多数的OpenCL兼容设备所含的处理单元(processing element)往往不止一个,换言之,设备内部还存在并行处理的可能性。第3章我们更多地关注这种并行处理,以及如何通过数据划分来最大化地利用设备内部的并行处理。


1_1

可移植性,向量运算以及并行编程使得OpenCL较之一般的C/C++更为强大、高效,但随之带来的也是计算系统更大的复杂性。在实际的OpenCL编程中,创建一系列不同的数据结构并协调它们之间的关系是必不可少的,尽管如此,要保持整个过程中任何事情都是明明了了,条理清楚,却并非易事,下一节我们将通过一个类比,让你对此有更深的认识。

相关文章
|
并行计算 C++ 异构计算
Nvidia 并行计算架构 CUDA 分析(一)——CUDA 简介
    CUDA(Compute Unified Device Architecture,统一计算设备架构)是由 NVIDIA 推出的通用并行计算架构,该架构使 GPU 能够解决复杂的计算问题。
4087 0
|
机器学习/深度学习 人工智能 测试技术
利用 UMA 使硬件加速器可直接用于 TVM
利用 UMA 使硬件加速器可直接用于 TVM
115 0
|
并行计算 openCL 算法
OpenCV算法加速(3)使用OpenCL
OpenCV算法加速(3)使用OpenCL
1340 0
|
编解码 算法 openCL
FFmpeg在Intel GPU上的硬件加速与优化
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/83572780 ...
5928 0
|
并行计算 openCL 异构计算
|
分布式计算 并行计算 openCL
《OpenCL实战》一 导读
1997年的夏天,我被震惊了。除了能在自己的专业(微电子工程)做实习生,我所能找到的最好的工作就是在一个专门研究高速信号处理的实验室做事,负责用C和MPI(Message Passing Interface,消息传递接口)编程实现二维快速傅里叶变换(fast Fourier transform,FFT)。
2451 0
|
openCL Java C++
《OpenCL实战》一第一部分 OpenCL编程基础
第一部分展示的是OpenCL语言,我们将详细讨论OpenCL的数据结构和函数,并通过例子来了解它们在应用程序中的作用。
2312 0
|
openCL 开发工具 异构计算
《OpenCL实战》一1.5 OpenCL标准和扩展
当你在通过网站www.khronos.org/opencl了解OpenCL时,你会看到一个名为opencl-1.1.pdf的重要文件。这其中包含了OpenCL1.1的标准,它所包含的是大量关于编程语言的内容。
2364 0
|
算法 openCL 异构计算
1.4 OpenCL应用程序的第一印象
现在,你应该对OpenCL的目标有了一个大致的了解。我还希望你能对OpenCL应用程序的运行过程有所认识。但如果想要更全面而深入地认识OpenCL,你还需要仔细阅读源代码。
1293 0