第七节:使用下一代CUDA硬件,快乐加速度
Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员。他在多个国家级的实验室进行大型并行运算的研究,并且是几个新创企业的合伙人。大家可以发邮件到[email protected]与他沟通和交流。
在关于CUDA(Compute Unified Device Architecture,即计算统一设备架构的简称)的系列文章的第六节,我探讨了使用CUDA PROFILER检测全局内存。在本小节,我要看下下一代的CUDA硬件。
CUDA和CUDA启动的设备共同发展,全新的每一代都提供了更强的性能表现。NVIDIA‘s 最近引入了GeForce 200-series和Tesla10-series产品,验证了发展的迅速,和上一代产品的价位差不多,但是功能却提高了两倍。另外,200系列还增加了一些有价值(而且不可或缺)的新功能。
原来G80中包含6.98亿个晶体管,而GTX280中包含14亿个晶体管,这清楚地表明了NVIDIA的下一代CUDA硬件是原来的两倍。我的经验表明,NVIDIA的确在200系列中很好地使用了这些晶体管。与上一代G80硬件相比,我的单精度代码不进行任何变化,在新硬件上的运行速度几乎是原来的2倍。
下面几项总结了200-series架构的新特征和功能:
- 硬件现在支持双精度算术运算(GTX280中有30个64位浮点单元)。
- 全局存储器更大、更快、更易用。联合规则略有宽松,因而也就更容易获得高全局内存性能,全局存储器带宽高于100 GB/s,几乎是G80架构的两倍。
- 每个硬件线程的单精度寄存器的数量已翻倍(尽管相对于上一架构,使用双精度时的可用寄存器数没有变化)。
- 200-series的共享存储器支持32位原子有符号和无符号整数函数,全局存储器支持64位函数。
- 200-series现在包含warp vote函数。
- 线程处理器数量几乎翻倍-从128上升到了240-每个多处理器支持更多的活动warp和活动线程。
- 200-series的硬件功能得到了提高,可同时执行MAD和MUL,从而有助于有些应用程序更好地达到顶峰性能。
让我们进一步来看下这对于CUDA意味着什么
对于诸多应用程序来说,最重要的一个新特征就是硬件双精度算术运算。NVIDIAGPUs的速度和大规模的并行性实现了用于大量数据的超级运算。处理超大型问题和数据集时,数字噪音可以快速积累(由于浮点不准确性),从而导致垃圾结果。例如,物理模拟可以突然展示惊人的非物理行为,而且以前有效的模拟可能变得不稳定,并开始生成无限值NaN或其他无意义的值。虽然并非对于所有计算问题都是必要的,但使用更高精度的浮点表示(比如64位双精度浮点数)确实很有帮助。(在以后的文章中,我们将介绍如何快速组合单精度与双精度计算来加速结果。)
200-series架构是第一个包括了硬件双精度的架构。正如对第一代产品所期望的一样,我们为性能改进保留了一些空间(因为多处理器中的线程处理器全部共享单个双精度硬件单元)。我的经验表明,只要仅在需要保留数字准确度时才使用双精度,性能只会有略微的降低。当然,问题因情况而异。
大部分程序员会发现更容易获得10-series构架的高性能啦。
NVIDIA把寄存器的数量翻倍后,CUDA程序员就更容易将足够数量的单精度数据上载至寄存器,以减少(或可能)全局内存存在的大多数瓶颈问题。因为双精度值需要双倍于单精度的存储空间(8字节对4字节),所以200-series上的双精度寄存器数量与G80和G92架构上的单精度寄存器数量一致。
全局存储器的带宽也几乎翻倍。
10系列主板提供了高于100GB/s的全局存储器带宽。对于32位浮点数,相对于G80和G92架构,10系列中的全局存储器带宽已经落后了,因为线程处理器数几乎翻倍,如下表1所示。
架构/卡 全局存储器带宽(GB/s) 处理单元数 全局存储器每秒内每个处理单元可用的32位操作数(只考虑带宽,单位:百万)
G80 / 8800 Ultra 104 128 203
10-series/ GTX 280 141 240 146
双精度 (64位浮点数) 性能复杂化,因为每个多处理器(8个线程处理器)有一个双精度单元,将其翻倍将消耗两倍带宽来应对。200-series 的CUDA开发人员可能会发现,使用单精度浮点数时带宽受限的应用程序在切换到双精度时,可能变为计算受限。
这个表格证实了NVIDIA硬件设计团队确实做得很出色,因为他们提供了一个新的产品,与上一代产品同一价格水平相比,它的全局存储器带宽和双精度功能几乎翻倍。
CUDA应用程度的一个强项就是:因为200-series 的聚合规则变得宽松了,就可以以更高效能的方式访问全局内存。CUDA Programming Guide的第5.2.2节更为详细地讨论了用来执行存储器事务处理的协议。以下是三个值得注意的特征:
为任何模式的地址请求实现了联合,包括对同一地址的多个请求。以前的架构需要按顺序访问字。实际上,这意味着更多的CUDA应用程序将获得极好的全局存储器性能,而且CUDA程序员将不再需要发明(如果可能)应急方案来保证其全局存储器访问模式的正常运行。
如果半warp地址字位于n个不同的分段中,则只执行n个存储器事务处理。例如,如果n=2,则与以前架构中发生的16个事务处理相比,将只执行两个存储器事务处理(即是原来事务处理的1/4)。
不幸的是,存储器中的未使用的字仍要读取,所以,它们浪费了带宽,尽管硬件将执行尽可能最小的存储器事务处理。
200-series支持有符号和无符号整数的原子操作。atomicExch()是个例外,它也是支持单精度浮动点数。原子函数对驻留在全局或共享存储器中的32位或64位字执行读-改-写原子操作。例如,atomicAdd()读取全局或共享存储器中某个地址的32位字,加一个整数,然后将结果写回同一地址。操作是原子的,表示保证在不受其他线程的干扰下执行,即在操作完成之前,没有其他线程可以访问此地址。
warp vote函数可用于200系列。如果需要的话,这些函数提供在warp的所有线程中执行快速谓词操作(比如,检查条件是真还是假)时必不可少的功能:
int __any(int predicate);
为warp的所有线程对指定的谓词求值,当且仅当谓词对所有线程求值为非零时,才返回非零。
最后,对硬件同时执行MAD和MUL操作能力的改进应该有助于一些应用程序实现更接近峰值性能的FLOP(浮点数操作)速率。
如需了解更多信息,请浏览 CUDA Zone 论坛。我还推荐在NVIDIA网站下载CUDA Programming Guide的最新版本。现在的版本是2.0b2,其中包括对最新特征和API的讨论。
这可能是升级到200-series CUDA启动设备的一个最佳时机。激烈的竞争(http://www.tgdaily.com/content/view/38243/135)促使对价格进行了明显调整,所以现在可能是进行交易的最佳时机!