GPU及GPU通用计算编程模型简介

转自http://blog.csdn.net/fengbingchun/article/details/19619491#comments

以下内容来自网络总结:

         NVIDIA公司在1999年发布GeForce256时首先提出GPU(图形处理器)的概念,随后大量复杂的应用需求促使整个产业蓬勃发展至今。

    GPU英文全称Graphic Processing Unit,中文翻译为”图形处理器”。GPU从诞生之日起就以超越摩尔定律的速度发展,运算能力不断提升。业界很大研究者注意到GPU进行计算的潜力,于2003年SIGGRAPH大会上提出了GPGPU(General-purposecomputing on graphics units)的概念。GPU逐渐从由若干专用的固定功能单元(Fixed Function Unit)组成的专用并行处理器向以通用计算资源为主,固定功能单元为辅的架构转变。

    尽管GPU计算已经开始崭露头角,但GPU并不能完全替代X86解决方案,很多操作系统、软件以及部分代码现在还不能运行在GPU上,所谓的GPU+CPU异构超级计算机也并不是完全基于GPU进行计算。一般而言适合GPU运算的应用有如下特征:运算密集、高度并行、控制简单、分多个阶段执行,符合这些条件或者是可以改写成类似特征的应用程序,就能够在GPU上获取较高的性能。

    GPU是显示卡的“心脏、大脑”,也就相当于CPU在电脑中的作用,它决定了该显卡的档次和大部分性能,同时也是2D显示卡和3D显示卡的区别依据。2D显示芯片在处理3D图像和特效时主要依赖CPU的处理能力,称为“软加速”。3D显示芯片是将三维图像和特效处理功能集中在显示芯片内,也即所谓的“硬件加速”功能。显示芯片通常是显示卡上最大的芯片(也是引脚最多的)。现在市场上的显卡大多采用NVIDIA(英伟达)和AMD两家公司的图形处理芯片。

GPU通用计算编程模型:

    GPU通用计算通常采用CPU+GPU异构模式,由CPU负责执行复杂逻辑处理和事务处理等不适合数据并行的计算,由GPU负责计算密集型的大规模数据并行计算。这种利用GPU强大处理能力和高带宽弥补CPU性能不足的计算方式以发挥计算机潜在性能,在成本和性价比方面有显著地优势。在2007年NIVDIA推出CUDA(Compute Unified DeviceArchitecture,统一计算设备架构)之前,GPU通用计算受硬件可编程性和开发方式的制约,开发难度较大。2007年以后,CUDA不断发展的同时,其他的GPU通用计算标准也被相继提出,如由Apple提出Khronos Group最终发布的OpenCL,AMD推出的Stream SDK,Microsoft则在其最新的Windows7系统中集成了DirectCompute以支持利用GPU进行通用计算。

    CUDA是一种将GPU作为数据并行计算设备的软硬件体系,硬件上NVIDIA GeForce8系列以后的GPU(包括GeForce、ION、Quadro、Tesla系列)已经采用支持CUDA的架构,软件开发包上CUDA也已经发展到CUDA Toolkit3.2(截止到2010年11月),并且支持Widows、Linux、MacOS三种主流操作系统。CUDA采用比较容易掌握的类C语言进行开发,而且正在开发适用于CUDA架构的用于科学计算的Fortran版本。无论是CUDA C-语言或是OpenCL,指令最终都会被驱动程序转换成PTX(Parallel ThreadExecution,并行线程执行,CUDA架构中的指令集,类似于汇编语言)代码,交由显示核心计算。

CUDA编程模型将CPU作为主机(Host),GPU作为协处理器(co-processor)或者设备(Device)。在一个系统中可以存在一个主机和若干个设备。CPU、GPU各自拥有相互独立的存储地址空间:主机端内存和设备端显存。CUDA对内存的操作与一般的C程序基本相同,但是增加了一种新的pinned memory;操作显存则需要调用CUDA API存储器管理函数。一旦确定了程序中的并行部分,就可以考虑把这部分计算工作交给GPU。运行在GPU上的CUDA并行计算函数称为kernel(内核函数)。一个完整的CUDA程序是由一系列的设备端kernel函数并行步骤和主机端的串行处理步骤共同组成的。这些处理步骤会按照程序中相应语句的顺序依次执行,满足顺序一致性。

CUDA SDK提供的API分为CUDA runtime API(运行时API)和CUDA driver API(驱动程序API)。CUDA runtime API在CUDA driver API的基础上进行了封装,隐藏了一些实现细节,编程更加方便。CUDA runtime API函数前都有CUDA前缀。CUDA driver API是一种基于句柄的底层接口,可以加载二进制或汇编形式的kernel模块,指定参数并启动运算。CUDA driver API编程复杂,但有时能通过直接操作硬件的执行实现一些更加复杂的功能或者获得更高的性能。由于它使用的设备端代码是二进制或者汇编代码,因此可以在各种语言中调用。CUDA driver API所有函数的前缀为cu。另外CUDA SDK也提供了CUFFT(CUDA Fast Fourier Transform,基于CUDA的快速傅立叶变换)、CUBLAS(CUDA Basic Linear Algebra Subprograms,基于CUDA的基本矩阵与向量运算库)和CUDPP(CUDA Data Parallel Primitives,基于CUDA的常用并行操作函数)等函数库,提供了简单高效的常用函数供开发者直接使用。

从CUDA Toolkit3.0开始支持NVIDIA最新的Fermi架构,最大程度上利用Fermi架构在通用计算方面的优势。CUDA 3.0也开始支持C++的继承和模板机制提高编程灵活性,同时CUDA C/C++内核现在以标准ELF格式进行编译,开始支持硬件调试,还增加了一个新的Direct3D、OpenGL统一协作API,支持OpenGL纹理和Direct3D 11标准,支持所有的OpenCL特征。

NVIDIA宣布最新版并行计算开发工具CUDA 6,相比此前的CUDA5.5有着革命性的巨大进步。CUDA 6的关键特性包括:同一寻址,可直接访问CPU内存、GPU显存,无需在彼此之间手动拷贝数据,可在大量编程语言中更简单地添加GPU加速支持。

OpenCL(Open Computing Language,开放计算语言)是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由用于编写kernels(在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。OpenCL提供了基于任务分区和数据分区的并行计算机制。

OpenCL最初由Apple公司开发,Apple拥有其商标权,并在与AMD,IBM,Intel和NVIDIA技术团队的合作之下初步完善。随后,Apple将这一草案提交至Khronos Group。2008年6月16日,Khronos的通用计算工作小组成立。5个月后的2008年11月18日,该工作组完成了OpenCL 1.0规范的技术细节。该技术规范在由Khronos成员进行审查之后,于2008年12月8日公开发表。2010年6月14日,OpenCL1.1 发布。

OpenCL也是基于C的一个程式语言,分为Platform Layer、Runtime、Compiler三个部分:Platform Layer用来管理计算装置,提供初始化装置的界面,并用来建立compute contexts和work-queues。Runtime用来管理资源,并执行程序的kernel。Compiler则是ISO C99的子集合,并加上了OpenCL特殊的语法。在OpenCL的执行模型中,有所谓的Compute Kernel和Compute Program。Compute Kernel基本上类似于CUDA定义的kernel,是最基本的计算单元;而Compute Program则是Compute Kernel和内建函数的集合,类似一个动态函数库。很大程度上OpenCL与CUDA Driver API比较相像

自从2008年12月NVIDIA在SIGGRAPHAsia大会上在笔记本电脑上展示全球首款OpenCL GPU演示以来,AMD、NVIDIA、Apple、RapidMind、Gallium3D、ZiiLABS、IBM、Intel先后发布他们自己的OpenCL规范实现(当一台机器上存在不同厂家的支持OpenCL的设备时,这样也给开发应用程序带来不统一的一些麻烦)。除了AMD和NVIDIA,其他厂商如S3、VIA等也纷纷发布他们支持OpenCL的硬件产品。

OpenCL是第一个面向异构系统通用目的并行编程的开放式、免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器、桌面计算系统、手持设备编写高效轻便的代码,而且广泛适用于多核心处理器(CPU)、图形处理器(GPU)、Cell类型架构以及数字信号处理器(DSP)等其他并行处理器,在游戏、娱乐、科研、医疗等各种领域都有广阔的发展前景,AMD-ATI、NVIDIA现在的产品都支持OPEN CL。

Directcompute是一种由Microsoft开发和推广的用于GPU通用计算的应用程序接口,集成在Microsoft DirectX内,允许Windows Vista或Windows 7平台上运行的程序利用GPU进行通用计算。虽然DirectCompute最初在DirectX 11 API中得以实现,但支持DX10的GPU可以利用此API的一个子集进行通用计算(DirectX 10内集成Directcompute 4.0,DirectX 10.1内集成Directcompute 4.1),支持DirectX11的GPU则可以使用完整的DirectCompute功能(DirectX 11内集成Directcompute 5.0)。Directcompute和OpenCL都是开放标准,得到NVIDIA CUDA架构和ATI Stream技术的支持。

Windows 7增加了视频即时拖放转换功能,可以将电脑中的视频直接转换到移动媒体播放器上,如果电脑中的GPU支持Directcompute,那么这一转换过程就将由GPU完成。其转换速度将达到CPU的5-6倍。Internet Explorer 9加入了对Directcompute技术的支持,可以调用GPU对网页中的大计算量元素做加速计算,另外Excel2010、Powerpoint2010均提供Directcompute技术支持。

AMD的流计算模型其实也包含了流处理器架构和相应的软件包。AMD在2007年12月发布运行在Windows XP系统下的Steam SDK v1.0, 此SDK采用了Brook+作为开发语言,Brook+是AMD对斯坦福大学开发的Brook语言(基于ANSI C)的改进版本。Stream SDK为开发者提供对系统和平台开放的标准以方便合作者开发第三方工具。软件包包含了如下组件:支持Brook+的编译器,支持流处理器的设备驱动CAL(Compute Abstraction Layer),程序库ACML(AMD CoreMath Library)以及内核函数分析器。

在Stream编程模型中,在流处理器上执行的程序称为kernel(内核函数),每个运行在SIMD引擎的流处理器上的kernel实例称为thread(线程),线程映射到物理上的运行区域称为执行域。流处理器调度线程阵列到线程处理器上执行,直到所有线程完成后才能运行下一个内核函数。

Brook+是流计算的上层语言,抽象了硬件细节,开发者编写能够运行在流处理器上的内核函数,只需指定输入输出和执行域,无需知道流处理器硬件的实现。Brook+语言中两个关键特性是:Stream和Kernel。Stream是能够并行执行的相同类型元素的集合;Kernel是能够在执行域上并行执行的函数。Brook+软件包包含brcc和brt。brcc是一个源语言对源语言的编译器,能够将Brook+程序翻译成设备相关的IL(IntermediateLanguage),这些代码被后续链接、执行。brt是一个可以执行内核函数的运行时库,这些库函数有些运行在CPU上,有些运行在流处理器上。运行在流处理器上的核函数库又称为CAL(Compute Abstraction Layer)。CAL是一个用C编写的设备驱动库,允许开发者在保证前端一致性的同时对流处理器核心从底层进行优化。CAL提供了设备管理、资源管理、内核加载和执行、多设备支持、与3D 图形API交互等功能。同时,Stream SDK也提供了常用数学函数库ACML(AMD Core Math Library)供开发者快速获得高性能的计算。ACML包括基本完整的线性代数子例程、FFT运算例程、随机数产生例程和超越函数例程。

面对NVIDIA在GPU通用计算上的不断创新,AMD也不甘示弱,不断改进自己的Stream SDK。截止到2010年11月,AMD发布了Stream SDK v2.2,能够在WindowsXP SP3、Windows 7和部分Linux发行版上运行,开始支持OpenCL 1.1规范和双精度浮点数操作。

 

参考文献:

1、  http://baike.baidu.com/view/1196.htm

2、  http://www.cnblogs.com/chunshan/archive/2011/07/18/2110076.html

3、  http://blog.csdn.net/caiye917015406/article/details/9166115

4、  http://www.rosoo.net/a/201306/16652.html

你可能感兴趣的:(GPU)