深入浅出谈CUDA

深入浅出谈CUDA

2009-2-5 作者: he21he21 来源: he21he21

关键字: CUDA NVIDIA 

  CUDA是什么?能吃吗?

  编者注:NVIDIA的GeFoce8800GTX发布后,它的通用计算架构CUDA经过一年多的推广后,现在已经在有相当多的论文发表,在商业应用软件等方面也初步出现了视频编解码、金融、地质勘探、科学计算等领域的产品,是时候让我们对其作更深一步的了解。为了让大家更容易了解CUDA,我们征得Hotball的本人同意,发表他最近亲自撰写的本文。这篇文章的特点是深入浅出,也包含了hotball本人编写一些简单CUDA程序的亲身体验,对于希望了解CUDA的读者来说是非常不错的入门文章,PCINLIFE对本文的发表没有作任何的删减,主要是把一些台湾的词汇转换成大陆的词汇以及作了若干"编者注"的注释。

  现代的显示芯片已经具有高度的可程序化能力,由于显示芯片通常具有相当高的内存带宽,以及大量的执行单元,因此开始有利用显示芯片来帮助进行一些计算工作的想法,即GPGPU。CUDA即是NVIDIA的GPGPU模型。

  NVIDIA的新一代显示芯片,包括GeForce8系列及更新的显示芯片都支持CUDA。NVIDIA免费提供CUDA的开发工具(包括Windows版本和Linux版本)、程序范例、文件等等,可以在CUDAZone下载。

  GPGPU的优缺点

  使用显示芯片来进行运算工作,和使用CPU相比,主要有几个好处:

  显示芯片通常具有更大的内存带宽。例如,NVIDIA的GeForce8800GTX具有超过50GB/s的内存带宽,而目前高阶CPU的内存带宽则在10GB/s左右。

  显示芯片具有更大量的执行单元。例如GeForce8800GTX具有128个"streamprocessors",频率为1.35GHz。CPU频率通常较高,但是执行单元的数目则要少得多。

  和高阶CPU相比,显卡的价格较为低廉。例如目前一张GeForce8800GT包括512MB内存的价格,和一颗2.4GHz四核心CPU的价格相若。

  当然,使用显示芯片也有它的一些缺点:

  显示芯片的运算单元数量很多,因此对于不能高度并行化的工作,所能带来的帮助就不大。

  显示芯片目前通常只支持32bits浮点数,且多半不能完全支持IEEE754规格,有些运算的精确度可能较低。目前许多显示芯片并没有分开的整数运算单元,因此整数运算的效率较差。

  显示芯片通常不具有分支预测等复杂的流程控制单元,因此对于具有高度分支的程序,效率会比较差。

  目前GPGPU的程序模型仍不成熟,也还没有公认的标准。例如NVIDIA和AMD/ATI就有各自不同的程序模型。

  整体来说,显示芯片的性质类似streamprocessor,适合一次进行大量相同的工作。CPU则比较有弹性,能同时进行变化较多的工作。

  CUDA架构

  CUDA是NVIDIA的GPGPU模型,它使用C语言为基础,可以直接以大多数人熟悉的C语言,写出在显示芯片上执行的程序,而不需要去学习特定的显示芯片的指令或是特殊的结构。

  在CUDA的架构下,一个程序分为两个部份:host端和device端。Host端是指在CPU上执行的部份,而device端则是在显示芯片上执行的部份。Device端的程序又称为"kernel"。通常host端程序会将数据准备好后,复制到显卡的内存中,再由显示芯片执行device端程序,完成后再由host端程序将结果从显卡的内存中取回。

  由于CPU存取显卡内存时只能透过PCIExpress接口,因此速度较慢(PCIExpressx16的理论带宽是双向各4GB/s),因此不能太常进行这类动作,以免降低效率。

  在CUDA架构下,显示芯片执行时的最小单位是thread。数个thread可以组成一个block。一个block中的thread能存取同一块共享的内存,而且可以快速进行同步的动作。

  每一个block所能包含的thread数目是有限的。不过,执行相同程序的block,可以组成grid。不同block中的thread无法存取同一个共享的内存,因此无法直接互通或进行同步。因此,不同block中的thread能合作的程度是比较低的。不过,利用这个模式,可以让程序不用担心显示芯片实际上能同时执行的thread数目限制。例如,一个具有很少量执行单元的显示芯片,可能会把各个block中的thread顺序执行,而非同时执行。不同的grid则可以执行不同的程序(即kernel)。

  Grid、block和thread的关系,如下图所示:

  每个thread都有自己的一份register和localmemory的空间。同一个block中的每个thread则有共享的一份sharememory。此外,所有的thread(包括不同block的thread)都共享一份globalmemory、constantmemory、和texturememory。不同的grid则有各自的globalmemory、constantmemory和texturememory。这些不同的内存的差别,会在之后讨论。

http://nvidia.e-works.net.cn/document/200902/article7438.htm

 

你可能感兴趣的:(CUDA)