200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > OpenCL与异构并行计算

OpenCL与异构并行计算

时间:2022-02-07 03:43:58

相关推荐

OpenCL与异构并行计算

原文:/changan2001/article/details/52955251

由于人工智能、深度学习和大数据处理随着移动互联的兴起,特别是对于图片、视频、语音等非结构化数据的挖掘、识别等以智能算法为核心的应用的兴起,“异构平台”成为各大互联网厂商追逐数据挖掘平台先进性的标志之一。与CUDA只能运行在NVIDIA GPU上相比,OpenCL由Khronos国际标准组织发布与维护,是一种针对通用并行计算的开放行业标准和跨厂商解决方案,可以实现“一次编写,多环境运行”,大大提高开发效率。OpenCL正在成为异构处理器的性能调优利器和开发语言。

异构并行计算包含两个子概念:异构和并行。

(1)异构是指异构并行计算需要同时处理多个不同架构的计算平台的问 题,比如目前主流的异构并行计算平台X86+GPU、X86+FPGA,以及目前正在研发中的ARM/Power+ GPU。

(2)并行是指异构并行计算主要采用并行的编程方式,无论是X86处理器,还是ARM和GPU处理器以及DSP,这所有的处理器都是多核向量处理器,要发挥多种处理器混合平台的性能也必须要采用并行的编程方式。

异构并行计算的出现缓解了处理器发展面临的两个主要问题:性能问题和功耗问题。

(1)由于不同的硬件适合处理不同的计算问题。合理地将不同类型的计算分发到异构平台的不同硬件上能够获得更好的计算性能,比如将需要短时间运行的串行计算分发给X86,而将需要长时间运行的并行计算部分分发给GPU。

(2)由于采用为特定应用优化的处理器。处理器设计可以依据应用的具体 特点来优化,故功耗方面也会获得更好的结果。

在性能和功耗都比较重要的情况下,如何衡量处理器的性能就变得复杂起来,对于计算性能至上的应用来说,性能更为重要。而对于功耗有特殊要求的应用来说,性能功耗比(每瓦功耗能够支撑的处理器计算能力)可能更为合适。

OpenCL全称为Open Computing Language(开放计算语言),先由Apple设计,后来交由Khronos Group维护,是异构平台并行编程的开放的标准,也是一个编程框架。KhronosGroup是一个非盈利性技术组织,维护着多个开放的工业标准,并且得到了业界的广泛支持。OpenCL 的设计借鉴了CUDA 的成功经验,并尽可能地支持多核 CPU、GPU或其他加速器。OpenCL 不但支持数据并行,还支持任务并行。同时 OpenCL 内建了多 GPU 并行的支持。这使得 OpenCL 的应用范围比 CUDA 广。为了能适用于一些更低端的嵌入式设备(比如DSP+单片机这种环境),OpenCLAPI基于纯C语言进行编写,所以OpenCL API的函数名比较长,参数也比较多(因为不支持函数重载),因此函数名相对难以熟记。不过,借助像Xcode、VisualStudio等现代化的集成开发环境,利用代码智能感知自动补全,其实开发人员也不需要刻意去死背OpenCL的API。

OpenCL覆盖的领域不但包括GPU,还包括其他的多种处理器芯片。到现在为止,支持OpenCL的硬件主要局限在CPU、GPU、DSP和FPGA上,目前在桌面端和服务器端提供OpenCL开发环境的主要有Apple、NVIDIA、AMD、ARM和Intel,其中Apple提供了一个独立的OpenCL框架并与自家的OSX系统完整地融合在一起;NVIDIA和AMD都提供了基于自家GPU的OpenCL在Windows和Linux上的实现,而AMD和Intel提供了基于各自CPU在Windows和Linux上的OpenCL实现。目前除了OSX系统上,NVDIA、AMD与Intel提供的OpenCL实现都不约而同地不支持自家产品以外的产品。由于硬件的不同,为了写出性能优异的代码,可能需要为不同的平台做相应的优化,这会对可移植性造成影响,这个需要权衡。

OpenCL 包含两个部分:一是OpenCL C语言(OpenCL 2.1将开始使用OpenCL C++作为内核编程语言)和主机端API;二是硬件架构的抽象。为了C 程序员能够方便简单地学习OpenCL,OpenCL 只是给 C11进行了非常小的扩展,以提供控制并行计算设备的 API 以及一些声明计算内核的能力。软件开发人员可以利用OpenCL 开发并行程序,并且可获得比较好的在多种设备上运行的可移植性。

为了使得OpenCL程序能够在各种硬件平台上运行,OpenCL提供了一个硬件平台层。同时各种不同设备上的存储器并不相同,相应地,OpenCL提供了一个存储器抽象模型。与CUDA相似,OpenCL还提供了执行模型和编程模型。

OpenCL不但包括一门编程语言,还包括一个完整的并行编程框架,通过编程语言、 API 以及运行时系统来支持软件在整个平台上的运行。总的来说,OpenCL具有以下特点:

❑ 高性能:OpenCL是一个底层的API,它能够很好的映射到更底层的硬件上,充分发挥硬件中各个层次的并行性,故能够获得很好的性能。

❑ 适用性强:OpenCL是一个抽象的API,它抽象了当前主流的异构并行计算硬件的不同架构的共性,同时又兼顾了不同的硬件的特点,因此具有广泛的适用性。

❑ 开放:OpenCL是由开放组织开发、维护的标准,不会被一家厂商所控制,故能够获得最广泛的硬件支持,比如AMD、Intel、NVIDIA、ARM、Qualcomm和联发科等都已经或正在其硬件上支持OpenCL。另外,还有像Altera等FPGA厂商也提供了OpenCL的SDK,并且能支持到当前比较新的OpenCL2.0标准。

❑ 无替代选项:无论是NVIDIA的CUDA,还是微软的C++ AMP和Google的RenderScript,都没有获得大量厂商的支持,只有OpenCL得到了几乎所有相关的主流硬件厂商的支持。

由于具有高性能、适用性强、开放和没有替代方案,OpenCL在未来必将在异构并行计算领域占有不可动摇的地位,甚至一统异构并行计算领域。

近十年来,异构并行计算平台、标准如雨后春笋般的出现,发展也是一日千里。从私有的CUDA、C++ AMP、Direct3D、Metal API,到开放的OpenCL、OpenACC、Vulkan。而老牌共享存储器编程环境OpenMP和分布式编程环境MPI也增加了对异构计算的支持,这些无一不显示着这个领域现在的辉煌,这是一个异构计算正在百花齐放的时代,在短期内这个领域依旧会呈现百花齐放的形态,甚至还会有新的平台、新的标准出现。而长期来说,最有可能笑到最后的,必定是OpenCL。

今天异构并行计算已经得到充分的发展并且还在进一步快速发展中,OpenCL和其他的异构并行计算工具已经应用到许多图像处理、视频处理及科学计算项目上,而这些工具自身也在快速进化中。近两年,许多科学计算以外的行业和领域(如互联网行业)正在应用异构并行计算来加快研究和产品化的步伐。计算的未来是异构并行的,异构并行的概念、应用在计算机及相关领域会越来越广。

4 基于OpenCL的编程示例

在本小节中以图像旋转的实例,具体介绍OpenCL编程的步骤。 首先给出实现流程,然后给出实现图像旋转的C循环实现和OpenCL C kernel实现。

4.1 流程

4.2 图像旋转

4.2.1 图像旋转原理

图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度, 通常是指绕图像的中心以逆时针方向旋转。假设图像的左上角为(l, t), 右下角为(r, b),则图像上任意点(x, y) 绕其中心(xcenter, ycenter)逆时针旋转θ角度后, 新的坐标位置(x',y')的计算公式为:

x′ = (x - xcenter) cosθ - (y - ycenter) sinθ + xcenter,

y′ = (x - xcenter) sinθ + (y - ycenter) cosθ + ycenter.

C代码:

void rotate(unsigned char* inbuf,unsigned char* outbuf,int w, int h,float sinTheta,float cosTheta){int i, j;int xc = w/2;int yc = h/2;for(i = 0; i < h; i++){for(j=0; j< w; j++){int xpos = (j-xc)*cosTheta - (i - yc) * sinTheta + xc;int ypos = (j-xc)*sinTheta + (i - yc) * cosTheta + yc;if(xpos>=0&&ypos>=0&&xpos<w&&ypos<h)outbuf[ypos*w + xpos] = inbuf[i*w+j];}}}

OpenCL C kernel代码:

#pragma OPENCL EXTENSION cl_amd_printf : enable__kernel void image_rotate(__global uchar * src_data,__global uchar * dest_data, //Data in global memoryint W, int H, //Image Dimensionsfloat sinTheta, float cosTheta ) //Rotation Parameters{const int ix = get_global_id(0);const int iy = get_global_id(1);int xc = W/2;int yc = H/2;int xpos = ( ix-xc)*cosTheta - (iy-yc)*sinTheta+xc;int ypos = (ix-xc)*sinTheta + ( iy-yc)*cosTheta+yc;if ((xpos>=0) && (xpos< W) && (ypos>=0) && (ypos< H))dest_data[ypos*W+xpos]= src_data[iy*W+ix];}

旋转45度

正如上面代码中所给出的那样,在C代码中需要两重循环来计算横纵坐标上新的 坐标位置。其实,在图像旋转的算法中每个点的计算可以独立进行,与其它点的 坐标位置没有关系,所以并行处理较为方便。OpenCL C kernel代码中用了并行 处理。

上面的代码在Intel的OpenCL平台上进行了测试,处理器为双核处理器,图像大小 为4288*3216,如果用循环的方式运行时间稳定在0.256s左右,而如果用OpenCL C kernel并行的方式,运行时间稳定在0.132秒左右。GPU的测试在NVIDIA的GeForce G105M显卡 上进行,运行时间稳定在0.0810s左右。从循环的方式,双核CPU并行以及GPU并行计算 已经可以看出,OpenCL编程的确能大大提高执行效率。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。