14.8_小结

14.8 小结

由于指令集和架构的不同,性能是以每秒衡量计算个体间作用力数目,而不是用每秒执行浮点运算次数。性能是在一个具有2个至强E5-2670处理器(类似于亚马逊的cc2.8xlarge实例类型)、64GB的RAM和4个GK104构架GPU(主频为800MHz左右)的沙桥系统上衡量的。该GK104构架GPU插在有16个PCIe 3.0插槽的双GPU主板上。

表14-4 来自CPU优化的加速比

表14-4总结了来自CPU优化的加速比。所有的测量均是在拥有双至强E2670 CPU(2.6GHZ)的服务器上进行的。在这个系统中,代码清单14-2中的传统CPU代码执行速度是每秒17.2M个个体间作用力,而单线程的SSE(单指令多数据)代码执行速度是每秒307M,是前者的17.8倍。正如预期的那样,多线程的SSE代码实现了良好的加速比,使用32个CPU线程获得每秒5650M个个体间作用力,是单线程的18倍。在结合SSE和多线程之后,这个平台上的CPU总加速比超过300倍。

因为我们从CPU优化得到了巨大的性能提升,使用GPU提升性能不再那么明显。[1] 在我们的测试中性能最高的内核(代码清单14-4中

的共享内存实现并以4为循环展开因子)进行每秒452亿个个体间作用力的计算,是使用最快的多线程SSE指令集的8倍。这个结果低估了CUDA在某些方面的性能的优点,因为用于测试的服务器拥有2个高端CPU,并且GPU为了降低功耗和散热均采取了降频措施。

此外,未来这2种技术都会有相应的改进。对于CPU,把该类负载移植到AVX(高级矢量扩展)将可能有双倍的性能,但是它只能在沙桥及其之后的芯片上运行,而且优化的CPU实现没有利用对称性。对于GPU,英伟达的GK110大约是GK104的2倍大(大约2倍快)。通过比较代码清单14-1和代码清单14-9的源代码(即GPU和SSE分别实现的个体间作用力计算的核心代码),显而易见,支持CUDA的因素并不只是性能上优于CPU。Vincent Natoli博士在他2010年6月的文章“Kudos for CUDA”中暗示了这一权衡。”[2]

类似的,我们发现在许多情况下,CUDA表达并行算法和CPU代码相比更紧凑、简洁和可读。这些领域包括石油和天然气、生物信息学和金融学。在最近的一个项目,我们将一个3500行的高度优化的C代码精简为大约800行的CUDA内核。优化的C代码塞入了内联汇编、SSE宏、循环展开和很多特殊情况,使其在未来难以阅读、理解算法含义并扩展。相比之下,CUDA代码更少并且可读性更好。最终,它将更容易维护。

虽然在这个应用程序中开发SSE的实现是可行的(一个核心的个体间作用力的计算使用了50行代码,见代码清单14-8),但是很难想象使用SSE指令集优化类似“类鸟群”这类应用的源代码会多么庞大。因为这类算法的每个个体必须进行条件评估,但是在CUDA硬件上运行时,这些代码将被按分支打包。SSE指令集支持断定形式(使用掩码和布尔指令序列,如用ANDPS/ANDNOTPS/ORPS来构建结果)和分支(通常使用MOVMSKPS提取条件进行评估),但是,要得到的此类负载的理论加速比极限需要巨大的工程投入,除非它们能用向量化编译器进行自动提取。

[1] 平心而论, 这一结论也适用于这本书中的其他负载, 例如第11章的SAXPY实现和第15章的归一化互相关实现。移植这些负载到多线程单指令多数据 (SIMD) 模式, 和CUDA版本比较, 需要把性能与工程投资、可读性以及可维护性进行权衡。
[2] www.hpcwire.com/hocwire/2010-01-06/kudos_for_cuda.html。

14.9 参考文献与延伸阅读

N-体问题及具有类似高计算密度的算法是获取高效加速比的资源,因为它们可以接近GPU计算能力的理论上限。下面只是无数类似于N-体这样的计算密集型方法的部分示例。

重力模拟

Burtscher, Martin, and Keshav Pingali. An efficient CUDA implementation of the tree-based Barnes-Hut n-body algorithm. In GPU Gems Emerald Edition, Wen-Mei Hwu, ed., Morgan-Kaufmann, 2011, Burlington, MA, pp. 75~92.

http://cs.mxstate.edu/\~burtscher/papers/gcg11.pdf

Harris, Mark, Lars Nyland, and Jan Prins. Fast n-body simulation with CUDA. In GPU Gems 3, Addison-Wesley, Boston, MA, 2007, pp. 677~695.

http://developer.nvidia.com/GPUGems3/gpugems3_ch31.html

分子模拟

Gtz, Andreas, Mark J. Williamson, Dong Xu, Duncan Poole, Scott Le Grand, and Ross C. Walker. Routine microsecond molecular dynamics simulations with AMBER on GPUs—Part I: Generalized Born, J. Chem. Theory Comput. 8(5), 2012, pp. 1542~1555.

Hwu, Wen-Mei, and David Kirk. Programming Massively Parallel Processors. Morgan-Kaufmann, 2010, pp. 173-188.

Hardy, David J., John E. Stone, Kirby L. Vandivort, David Gohara, Christopher Rodrigues, and Klaus Schulten. Fast molecular electrostatics algorithms on GPUs. In GPU Computing Gems, Elsevier, Burlington, MA, 2011, pp. 43~58.

Stone, John E., James C. Phillips, Peter L. Freddolino, David J. Hardy, Leonardo G. Trabuco, and Klaus Schulten. Accelerating molecular modeling applications with graphics processors. Journal of Computational Chemistry 28(2007), pp. 2618~2640.

http://cacs.usc.edu/education/cs653/Stone-MDGPU-JCC07.pdf

Stone, John E., David J. Hardy, Barry Isralewitz, and Klaus Schulten. GPU algorithms for molecular modeling. In Scientific Computing with Multicore and Accelerators, Jack Dongarra, David

A. Bader, and Jakob Kurzak, eds. Chapman&Hall/CRC Press, London, UK, 2010, pp. 351~371.

类鸟群

da Silva, A.R., W.S. Lages, and L. Chaimowicz. Boids that see: Using self-occlusion for simulating large groups on GPUs. ACM Comput. Entertain. 7(4), 2009.

http://doi.acm.org/10.1145/1658866.1658870