浅谈CUDA的局限性

nvidia的CUDA(Compute United Device Architecture)推出来以后,受到了无数nvidia fans们的追捧,连许多非图形图像领域搞技术的人员都开始玩起了CUDA。本人有些懒惰,在技术上除了理论和架构上的东西外,其他的例如语言细节等东西都是在实际工作需要时才去学,所以只到昨天,我才花了点时间在网上搜了些CUDA tutorial看了下(作为曾经的骨灰级N fans,惭愧ing )

但如题所示,我写这篇blog不是为了介绍CUDA的“强大”,而是打算喷一喷它:-)

虽然会有错误,但我还是按照我的理解,把它的局限性总结如下,欢迎大家拍砖或开喷。
首先是语法和API层面的:
1. 在GPU上执行代码中不能分配动态内存。也就是说要么在computation kernel中使用shared memory来存放临时数据,要么事先在CPU端分配好;
2. CUDA是基于C语言的。先别说C99标准,因为CUDA支持exception handling肯定是没戏的(后面还会提到这个),就是连ANSI C里的函数指针都是没法在CUDA里用的。据我了解现在用到C语言的场合,比如嵌入式设备和一些网络设备,几乎都用到了函数指针来实现类似C++中的virtual function的机制;
3. 必须由CPU(CUDA程序的host)来分配block/thread。而在目前多线程程序里,经常是一个作为从属的worker thread还会拥有更底层的worker thread,而它们对于上层的thread可以是透明的;
4. Thread之间通信原语只有synchronize。而我们在写多线程程序是,偶尔还是会通过某种方式(比如全局变量和共享内存等)在线程间传递数据的;

以上这些局限是语言层面的,在我们认识事物时,这些是属于表象的范畴。那么本质是什么呢?下面要谈的就是我所认为更为本质的局限性:
1. 关于computation kernel中无法使用函数指针——GPU储存程序的方式与x86 CPU还是有很大不同的。x86 CPU把可执行代码的储存空间和数据储存空间统一编址,在最早的8086中都是这样,通过一组寄存器(e.g. ECS,EIP)来指示当前程序执行的位置。而就我所接触过hardware spec的GPU来说,指令代码是存在GPU chip里的指令slot单元,这些单元不和显存统一编址。所以对于跳转指令,CPU可以有jmp,jne等,以及帮你自动搞定stack push/pop操作的call, 这些指令后面都可以跟一个立即数,寄存器或某种寻址方式,后两者都可以用来实现函数指针。而GPU的跳转指令由于编址的原因,只能跟立即数(理由自己想想),所以...

2. 关于内存分配——这个解释也很简单,CPU为啥能搞内存分配?靠的是OS和runtime的支持,OS底层有干了啥?无非也就是为某个进程的GDT(全局描述符表)里增加PTE(page table entry),即把一段物理内存映射到当前进程的virtual address space。GPU为啥不能搞内存分配?原因就是没有runtime的支持,GPU程序都是裸体在跑的:-) 或许将来可以在显卡的bios里实现一些库函数完成动态内存分配,但软件标准要先提出来;

3. GPU没有stack!这造成了当前几乎所有的多线程架构应用程序(典型的应用如渲染器)没法很容易的移植到CUDA架构,比如渲染器肯定会支持的ray tracing算法,在没有stack的系统上实现,需要很多技巧,在我之前看过不少在GPU上做ray tracing的paper中:
 a. 要么是以空间换时间(如uniform grid表示场景)
 b. 要么是以牺牲性能来使ray tracing能够在GPU上跑(如stanford那篇"Interactive k-D Tree GPU Raytracing"中的一些算法)
 c. 还有些设计更巧妙的,利用上GPU上特有硬件机理的(比如mipmap),如时间比较近的“Fast GPU Ray Tracing of Dynamic Meshes using Geometry Images”,但它们局限性相当大
能在GPU上做ray tracing,速度一定很快?事实是这些paper的结论也只是相同场景下的速度和高端CPU的”具有可比性“。所以GPU没有stack这一点的确限制了CUDA的应用范围,或许明年nv和amd将推出DX11硬件是最后一代stackless的GPU了。

4. GPU性能的噩梦——随机内存访问。据我对CUDA的皮毛认识,是不提倡在CUDA程序中做任何的随机访问的,另外在CUDA教程里也花了不少篇幅来介绍什么样的memory access是cache friendly的。其目的就是为了降低cache missing rate,可现在的显存频率不是很高了吗?比如2G Hz的GDDR5。这样认为的朋友应该补充一下memory latency的知识,我这里不罗嗦。而对于CPU,为什么它能够适应各种随机内存访问和动态跳转?那是因为它画了相当数量的电路去完成”比GPU智能得多的caching机制, 预先分支判断和指令乱序执行等“。对比CPU,GPU在这方面过于落后,而且nvidia似乎不注重在这方面的投入,而认为可以通过其软件(driver,compiler)搞定优化,个人认为有些过时了。

先写这么多,总之我个人看法是:CUDA由于和传统的编程思维有较大区别,以及在无法兼容很多算法,导致了其应用局限性很大。目前CUDA能完胜CPU的领域仅限于静态图像处理,连video的encode/decode都只能在部分阶段参与。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值