Jun 12 2008

Cuda技术革命一瞥

Published by shinjikun at 12:07 am under 科学与科普 1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

背景

当前在老百姓眼中有关计算机技术的最时髦的词汇莫过于“多核”了。从前年起,“多核”这个东西就走进了家用的行列,现在购置的计算机基本上都是双核心或者是四核心的。由于“硅芯片主频的物理极限已经达到,CPU将来的发展即将走向多核方向”,得到的结果就是AMDIntel两家公司的竞争进入了进一步的白热化阶段。

其实一台计算机多个计算单元的现象很早就出现了。古代有所谓的“解霸卡”,这是一个专门为视频解压处理而设计的处理器,原理基本就是一个为浮点优化的CPU。把视频解压的工作分给解霸卡,而CPU则留下进行更重要的工作。之后Intel推出了MMX指令集,这种卡旋即消失。后来著名的就是Voodoo卡(以及同时代的各类3D加速卡),这是现代显卡的雏形。他把浮点计算分离出来,并且直接加入了贴图和灯光的特性,使得3D游戏开始普及。伴随着DirectX技术的成熟,就产生了现代显卡。现代显卡指的是支持一定的渲染标准的显卡,如OpenGL标准、DirectX标准等。通过这种设计,程序员可以方便的通过OpenGLDirectX接口来编制程序,而不需要考虑具体的硬件类型。这是一个跨时代的突破。

在普通的情况下用显卡进行渲染,速度要比用普通的CPU计算快上几千倍,而且图像大小(像素数)越大,加速的比例就越大。这是显卡的自身特性造成的。显卡当中,相当于封装了成百上千个“核心”,所有的“核心”可以一起处理。由于GPU的计算是一种特殊的计算任务,即所计算的每一个像素之间不需要(或者用方法使它不需要)考虑先后顺序,那么如果有了上百万个线程,就可以让所有的像素同时渲染,这样所有的像素就可以在一个像素的时间内计算完成。而实际上在CPU上的运算通常是做了一件才能再做一件,这样就算有一万个核心,在前一个结果计算出来之前,其他的线程只能傻傻等待,这就相当于一个核心了,因此CPU多核心的发展要比GPU慢得多。由于两者计算的目的不同,造成他们的构架不同。因此显卡与CPU的计算任务通常是分离的。

实际上,假如你知道你现在的将要做的计算是可以高度并行的密集型计算,那么就应该使用GPU来进行运算。然而一般的显卡却没有这样的功能,它通常只能处理矩阵、贴图、采样等等的已经有实际图形学意义的问题,而对其他的运算,只能转换成图形运算才能进行。利用GPU进行通用目的计算(General Purpose Computing)的想法很早就有了,成熟的产品有GPGPU语言等。我曾经历尽千辛万苦编写了一份在显卡上进行FFT计算的程序,其代码量之庞大简直是骇人听闻。普通的FFT150行以内就可以完成,而GPUFFT计算则需要至少千行(利用GPGPU语言的话代码量会少很多,但是相对于FFT程序,这个语言产品本身的空间就不小)。之所以有如此之多的代码量,是因为需要将各种数据通过一个图形接口(一般是扩展的OpenGL)发送到GPU,计算之后,再通过这个图形接口接收结果。

另外,程序员从娘胎里带出来的“一根筋”(单线程,算完一个再用结果来算另一个)的思维习惯是非常不容易改变的。除非是像渲染 这种明显就应该是并行运行的东西,其他的东西找出成熟的并行算法非常困难。这就意味着,多核的潜力还必须得到进一步的开发。当然有一个简单的方法就是运行很多的进程,可以以此把CPU塞满。

原理

nVidia公司一直以来是显卡界的两位登峰造极者(nVidiaATI,后者前些日子与AMD公司合并为AMD&ATI公司) 之中更时尚的一位。2006118日,nVidia抛出了他们的通用目的GPU计算的方案CUDA——Compute Unified Device Architecture 即计算统一的设备架构。这是业界第一个可以用C语言进行编程的通用目GPU计算解决方案。实际上走在了时间的前头。

CUDA的原理基本如下:

把 大量的线程(这个概念与一般的不同,他是更轻量级的,更快速的)分布在一个个的“块”中。每个块共享一段指令和数据,而块中的每一个线程只能访问到本块的 数据以及外层的共享数据,访问不到块之间的数据。外部的驱动程序负责把所有的数据和指令拷贝到块中,然后所有的线程开始同时运行。当最后一个线程结束后运 行结束。

这样,指令也相同,数据也相同,因此既不会有换页问题,也没有缓存刷新问题(考虑到实际上GPU是不具备与内存速度不同的缓存的,这个速度的提升是靠多点同时访问和显卡版内的超大带宽得到的——总之就是比那么多个CPU要快啦!囧)。仅仅这样,我们就可以得到前所未有的强大速度提升,这靠的是无以伦比的超大线程数!

在编程方面,如果我们想向一个块中写入指令,只需要像C/C++一样编写一个函数,然后用CUDA的简写方法进行调用(可以自由设置块数和线程数)。之后CUDA编译器nvcc自动将代码编译成CPU代码和GPU代码,并让GPU代码可以自动的发送到适当的快中。期间的一切硬件问题程序员都不需要管,结果就是写一个CUDA程序和写一个普通的C程序一样方便。

我现在的显卡的参数是这样的(不是什么高端的显卡,每个人的显卡都有类似的能力):14个多核处理器,每个多核理器112个核心,每个核心65536*65536*1个格点(这个不能达到最大值。实际使用中取决于显卡的当前状态),每个格点有512*512*64块,每块同时可以运行512个线程(同时每块具有8k个寄存器)。可以粗略计算一下,就算我们只用到了一个格点,我们就可以得到85亿个线程。这就是说只要我们的显存(才十亿字节)足够,那么我们就可以想开多少个线程就开多少个线程。

根据官方发布的资料,如果是更高端的Tesla卡的话,可以每秒进行500G次浮点运算。CPU浮点运算平均大约消耗400周期的话,那么CPU每秒可以进行2*3G/400=0.15G次浮点运算。相比之下大约能快3000倍左右。但是在这种构架只下,最花费时间的操作不再是运算,而是把指令和数据从内存中拷贝到显存中的过程。现在的GPU(PCI-E)带宽在4G/s左右,这就是我们每毫秒可以把4百万字节数据从内存调入到显卡中,这对于大部分的应用而言可能足够了,但是如果需要更高端的计算性能,恐怕只有等待显卡的插槽更新换代了。

应用

我有幸参加了CUDA技术的创始人之一David Kirk博士在清华进行的讲座。讲座中提到了CUDA从开始到现在不足两年的时间里的大量应用。实际上有些是令人比较失望的——在一般的状况下,CUDA的运行速度只达到了CPU的一百倍到一千倍左右,并没有达到那么夸张的地步——不过这依然足够改变人们的工作方式了。

  • 神经网络模拟。有一个人建立了一个巨大的神经网络,用来模拟真实生物的神经活动。众所周知,每个神经细胞都可以当作是并行运行的,因此这个模型非常适用于CUDA
  • 股票分析软件。它是以复杂计算为基础,进行整个美国股市的实时分析的一个软件。由于股票之间的情况异常复杂,造成经济学上的公式无法准确预测时间稍微一点的大盘情况。然而,有了CUDA,我们就可以在几百毫秒之内计算出当前的全美的大盘走势,这通常将花费数分钟时间,等我们得到结果之后,它已经没用了。CUDA让股票分析软件从不可能成为了可能。
  • 分子流体模拟。这是中科院物理所的一位老师做的。他就是把分子的范德化力(其模型相对复杂)考虑进去。他制作了一个包含几亿个分子水滴,然后进行 模拟。由于每个水滴之间的范德华力只在周围的范围内有效,因此可以把每个分子的受力状况看做是不相干的或弱相干的。这也很适于CUDA
  • 地震研究与模拟。地震研究方面的一个重要问题就是如何快速的处理地震数据。这让我想起了当时MRI刚被发明的时候,虽然有了实验数据,但是算不出结果来。动用了当时最先进的军用超级计算机才得到一张图像。现在的医学器械里,MRI是太常见的东西了。这说明将来我们有可能处理更多的地震数据,解开地震规律之谜。

展望

CUDA是一项以提高计算性能为目的的新兴技术,但是其影响将远远超出“计算”的范围。GPGPU是一个神奇的事物,因为如果处理得好的话,那么可以几千倍的打破摩尔定律,而跳跃到下一个时代。GPGPU的问题就在于编程的痛苦性太高,而CUDA就是为此目的而设计。就如同David Kirk所言,计算性能提高十倍会使现在的工具变得很方便,计算性能提高一百倍会使现在的软件更新换代。而计算性能提高一千倍,则会彻底改变人们的工作方式。曾经不可能的慢慢变为可能。我们期待着CUDA技术以及未来的新的GPGPU技术能够带领我们(程序员和用户)走向新的时代!

6 Responses to “Cuda技术革命一瞥”

  1. zeroyearon 12 Jun 2008 at 12:51 pm  Vote: Add rating 0  Subtract rating 0  

    呵呵,关于“地震研究与模拟”的那段是否太凑篇幅了?按你这样写,这段里面的“地震”二字貌似可以换成任何东西吧?另外,读者网上的诸多帖子大多强调这么一种观点:地震的问题,计算固然重要,但迫在眉睫的貌似还是数据的采集和测量。
    文章以“多核”开篇,后来只谈论显卡管线,本质固然一样,但没有说清楚其实此核非彼核,可能反而带来误导。出现的术语太多了,而且光那几家公司和标准的“恩恩怨怨”都可以写好几本书了,一个帖子不能涉及太多内容。我懂些图形学,所以读起来没问题,但换成普通读者,这个文章放在“科普”类里面难度可能太高了些,建议再开一类:)

  2. shinjikunon 12 Jun 2008 at 2:41 pm  Vote: Add rating 0  Subtract rating 0  

    To Zeroyear:
    谢谢您的提醒,我觉得那些恩怨实在是太有趣了,一不小心写了好多。其实这篇文章写了一半以后死机了,居然就没有了,我从新写了一遍。之前那一遍里面有更多的恩怨问题。其实主要就是想表达为什么CUDA会出现,而且为什么趁现在这个时候出现。我可能还要再整理整理。CUDA这个想法如果更成熟一点,他可能会产生一次翻天覆地的革命。现在还看不出来,观望中。

    那个地震是这样的,那些例子不是我凭空想出来的,而是确实已经有了这些应用,我并不是因为最近在讨论地震问题而把它加上的。当时讲了确实有一个专门研究地震的机构使用CUDA进行工作。讲座是4月份,那时还没有发生地震。实际上国外的地震研究机构已经开始关注CUDA。

    我特意为了CUDA买了一台电脑,8000块左右,开始学习如何写CUDA程序。写多线程程序很难的,CUDA还有一个问题就是它对锁的支持太浅了。不过也可以理解,512个同时运行的线程做一个锁是多么大的代价啊。所以最后必须考虑如何计算才能不需要同步。我现在还处在研究学习阶段,不过就是希望等CUDA成为主流的时候,我可以走在时代的前面。

  3. zeroyearon 12 Jun 2008 at 5:05 pm  Vote: Add rating 0  Subtract rating 0  

    我是从科普短文写做的角度来找茬的,呵呵。不同的阵地有不同的目标。对于科普站点,主要的讨论应该紧密围绕科普,而不是靠向学术和技术前沿的细节,否则读者容易生厌生俱,那可还怎么普啊?这也就是所谓公众理解科学的问题。
    方舟子的短文同样会介绍学术和技术前沿,但是文章的组织和表达能够让人爱读,更不会产生惧怕科学的感觉。
    我嘴皮子说说当然很容易,写起来是很难的。但你的目标要高些,至少超过方舟子,你当然不必像方舟子那样涉猎甚广,仅限于计算机这一块的科普短文,你要超过方舟子,哈哈!

  4. shinjikunon 12 Jun 2008 at 5:36 pm  Vote: Add rating 0  Subtract rating 0  

    呵呵谢谢您抬举我。
    我又看了看,怎么看怎么不像科普,而像是篇蹩脚报道或者纪实文学。我要改一改。另外,好像观点有失偏颇,我要再加入一点负面内容才行。
    总之昨天夜里写好就发,是有点潦草了。

    另外:分类改成“前沿纪实”好像改起来要简单一点。囧囧囧

  5. shinjikunon 12 Jun 2008 at 5:45 pm  Vote: Add rating 0  Subtract rating 0  

    完啦,我现在觉得这玩意儿要写成科普真是太难了。。。怎么跟我的同学他们都听不懂。。。难道这只是我一厢情愿的认为大家能懂?

  6. alpha000001on 12 Jun 2008 at 9:42 pm  Vote: Add rating 0  Subtract rating 0  

    鼓励下!
    等着看改成科普类型的,现在看起来有点儿累囧。

Trackback URI | Comments RSS

Leave a Reply



This blog will be closed at 2009/02/28.
Please update your links.