第1章引言11 CUDA编程模型的目标是占据桃肉中更多部分的热门应用。 串行部分 传统CpU区域 圆数据并行部分 屬GPGPU区域 ■障碍物 图1-4应用程序的串行和并行部分所占比例 1.4并行编程语言与模型 在过去的几十年里,人们相继提出了很多并行编程语言和模型Mattson,2004]。其中 使用最广泛的还是为可扩展的集群计算设计的消息传递接口Message Passing Interface, MP)和为共享存储器的多处理器系统设计的OpenMP。MPI是一种集群中的计算结点之间 相互不共享存储器的模型MPI,2009]:结点之间的数据共享与交互都通过显式消息传递的 方式实现。MPI成功应用于高性能科学计算领域。用MPI模型编写的应用程序已经成功运 行在多达100000个结点的集群计算系统上。要想把应用程序移植到MPI中,开发人员还 需要投入更多的精力。然而,如果计算结点之间缺乏共享存储器的机制,那么可能需要付 出更多努力。另一方面,CUDA在GPU中并行执行时提供共享存储器的机制以解决上述 难题。至于CPU和GPU之间的通信,目前CUDA还只能在CPU与GPU之间提供有限共 享存储器的功能。程序员应该管理CPU和GPU之间的数据传输,采用的方式类似于“单 向”消息传递,这正是MPI缺乏的功能,长久以来都被认为是MPI的主要缺点。 由于OpenMP支持共享存储器,因此在编程方面它也与CUDA有同样的优势,但它支持 的计算结点规模不能超过200个,因为受限于线程管理的系统开销和缓存一致性的硬件要 求。CUDA采用简单的、低系统开销的线程管理,且没有缓存一致性的硬件要求,因此能 实现更高的可扩展性。但是,我们会看到由于要权衡可扩展性,CUDA和OpenMP的应用都
12 大规模并行处理器编程实战 不广泛。另一方面,许多超级应用更适合于CUDA的简单线程管理模型,因此在采用CUDA 技术时可扩展性和性能都很好。 在管理并行代码结构时,MPI和OpenMP都与CUDA在很多方面相类似,尽管OpenMP 编译器在并行执行过程中更多的是自动化管理。目前正在进行的许多研究工作旨在使 CUDA更多地采用自动化的并行管理和优化CUDA工具链的性能。如果开发人员有MPI 和OpenMP方面的经验,就会发现CUDA很容易掌握,特别是对CUDA性能优化技术方 面的理解将更加深刻。 最近,计算机行业内的几家大公司,如苹果、Inter、AMD公司旗下的ATI以及NVIDIA 公司,共同开发了一套标准编程模型,称之为OpenCL[Khronos,2009]。与CUDA类似, OpenCL编程模型定义了语言扩展和运行时API,使程序员可以在大规模并行处理器中进 行并行管理和数据传递。OpenCL是标准编程模型,用OpenCL开发的应用程序在支持 OpenCL语言扩展和API的所有处理器上,即使不进行修改也一样能运行。 读者可能会产生疑问,为何本书不是基于OpenCL编写的。主要原因是,本书在OpenCL 还处于萌芽阶段时已经写完。在编写本书时,OpenCL的编程结构与CUDA相比仍处于较 低水准,使用起来还很繁琐。此外,在同时支持CUDA和OpenCL这两种技术的平台上, OpenCL的运行速度还远远低于CUDA的运行速度。由于在大规模并行处理器编程中速度 是一个重要指标,因此我们预计在未来很长一段时间内,大部分的大规模并行处理器编程 人员仍将继续使用CUDA技术。最后,同时熟悉OpenCL和CUDA技术的开发人员肯定 会知道OpenCL和CUDA的主要功能有着惊人的相似之处,也就是说,一个CUDA程序 员很容易掌握OpenCL编程。本书后续章节会更为详细地分析两者的相似之处。 1.5 综合目标 我们的主要目标是教会读者如何进行大规模并行处理器编程以实现高性能,并且我们 的方法不需要大量的硬件专业知识。有人曾说过,如果在并行编程时不考虑性能问题,那 么这种编程是一件相当简单的事情。读者几乎可以在一个小时内编写一个并行程序。但是, 我们花费大量章节讲解的是如何进行高性能并行编程,只要读者有很好的洞察力并能正确 地从事该编程工作,我们相信这并不是什么难事。特别要强调的是,本书集中讲解计算思 维这方面的技术,这会使您更多地考虑高性能并行计算。 值得注意的是硬件的体系结构功能也有局限性。很多芯片上的高性能并行编程要求程 序员了解硬件的工作原理。要掌握这些工具和设备可能需要花费10多年的时间,因此很多 程序员没有这些知识也照常工作。我们不会把计算机体系结构作为独立的部分来讲解,而 是把计算机体系结构中的核心知识作为高性能并行编程技术的一部分来讨论
第1章引 言13 本书第二个目标是讲解如何编写功能正确的、可靠的并行程序,这是并行计算中的技 巧问题。过去曾从事过并行系统方面工作的开发人员会知道,仅保证初始性能是远远不够 的。我们面临的挑战是如何在可以调试代码和支持用户的情况下实现高性能。CUDA编程 模型关注的焦点是数据并行性,我们将帮助读者在他们的应用程序中实现高性能和高可 靠性。 本书第三个目标是通过探讨一些方法来使目前的并行编程实现可扩展性,能适应未来 硬件更新换代的要求。对于未来的计算机,程序并行化程度会越来越高,程序运行速度也 会比现在的计算机更快。我们想帮助读者掌握并行编程,以便随着新一代计算机的出现, 程序的性能有所提升。 读者要想达到上述目标,需要掌握相当多的技术知识,因此本书主要讨论并行编程的 设计原理和模式。我们不能保证本书能覆盖所有相关知识,但是我们从中选取最有用也是 经得起考验的技术进行深入研究。为了补充读者的知识和经验,我们将推荐一个相关参考 文献列表。接下来我们准备对本书的其余部分做一个简单的概述。 1.6 本书的组织结构 第2章主要回顾GPU计算的发展历程。首先概述图形硬件发展到具有很强的编程能 力的变革,然后讨论GPGPU的发展历程。CUDA GPU的发展历程决定了它当前的功能与 局限性。如果读者能深入了解这些发展史,则更容易理解硬件变革的当前状态以及未来的 发展趋势,硬件变革将继续影响应用程序类型,这种影响受益于CUDA技术。 第3章主要介绍CUDA编程。本章的知识依赖于读者之前有C语言编程的相关经验。 本章先介绍CUDA作为对C轻描淡写的扩展,支持异构CPU/GPU连接计算并广泛使用 SPMD(Single-Program Multiple-Data,单程序多数据)并行编程模型。然后向读者阐述编写 程序的思维过程:(1)确定应用程序中要并行化的部分,(2)将并行化代码中要用到的数据分 离出来,具体方法是用API函数在并行计算设备上分配存储空间,(3)用API函数将数据传 输到并行计算设备上,(4)在并行化部分开发一个kernel函数,该函数由其中的个别线程执 行,(⑤)为由并行线程执行而启动kernel函数,(6)最后调用API函数将数据传回主机处理器。 第3章主要是介绍CUDA编程模型的概念,以便读者能编写简单的CUDA并行程序,但 事实上它涵盖了很多基本的编程技巧,这些技巧在基于任何并行编程模型设计并行应用 程序时都适用。我们用一个可运行的矩阵乘法(matrix-matrix multiplication)示例贯穿整章 内容。 第47章主要是让读者更深入理解CUDA编程模型。第4章的主要内容是线程的组织 结构和执行模型,要求读者掌握线程的执行方式和基本的性能概念。第5章主要介绍CUDA
14 大规模并行处理器编程实战 的特殊存储器,这些存储器用来存储CUDA变量以便提高程序执行速度。第6章则侧重介 绍CUDA kernel函数的主要特点以便能提高性能。第7章的主要内容是数据的浮点表示以 及精度和准确度的概念。虽然这些章节以CUDA技术为基础,但它们能帮助读者建立一般 并行编程的基础。从基础开始学习能够帮助读者更彻底地掌握本书,也就是说,我们首先 以某个特殊编程模型为背景学习并行编程模型的概念,这为我们建立了坚实的基础,以便 把学到的知识推广到其他的编程模型中。事实上本书也是这么编写的,我们可以从CUDA 模型中借鉴具体经验。CUDA模型中更为深入的体验使我们变得更为成熟,这会帮助我们 理解即使是与CUDA模型毫不相关的概念。 第8章和第9章则对两个实际应用程序案例进行深入研究,带领读者经历对应用程序 并行化和优化的思维过程而达到明显加速的目的。对于每个应用程序,首先确定可供选择 的多种方法,这些方法用于表述并行执行的基本结构,然后比较供选择的每种方法各自的 优缺点。最后为实现高性能,我们将讲解代码转换的步骤。这两章帮助读者把先前几章的 内容系统地组织起来,并为读者自己的应用程序开发项目做准备。 第10章将并行编程技术概括为问题分解原理、算法策略和计算思想。它包括在程序中 如何组织计算任务,从而使它们之间可实现并行化。我们首先要讨论的是如何把组织抽象 的科学概念的过程转化成计算任务,不管采用串行还是并行编程方式,这都是编写高质量 应用软件的首要步骤。这一章还将介绍并行算法结构和它们对应用程序性能产生的影响, 这些都以CUDA的性能调整经验为基础。这一章最后得出关于并行编程风格与模型的结 论,帮助读者在更为广阔的背景下运用自己的知识。学习这一章后,读者可以把SPMD的 编程风格推广到其他并行编程风格中,如OpenMP中的循环并行方式和p-thread编程中的 分叉-合并(fork-join)方式。尽管本书并没有涉及这些可选择的并行编程风格,但是我们希 望读者以本书中学到的知识为基础,可以掌握其他的并行编程方式。 第ll章从cUDA程序员的角度介绍OpenCL编程模型。读者会发现OpenCL与CUDA 极为相似。最大的不同之处在于OpenCL调用API函数来实现如启动kernel函数和标识线 程之类的功能。API函数的使用使OpenCL变得更为繁琐,但CUDA程序员已经掌握了理 解和编写OpenCL程序的所有必要知识和技能。事实上,我们相信最好的方式是先讲述 CUDA编程,再讲述OpenCL编程。本章通过将OpenCL所有主要功能与CUDA对应功能 关联来证明了上述观点。我们还将通过把简单的CUDA示例改编为OpenCL示例来阐述这 些功能的使用。 第12章提供一些结论性的评价,并展望大规模并行编程未来的发展前景。我们重申 本书的目标,并概述各个章节如何有机地组织起来,从而达到这些目标。然后,我们对大 规模并行处理器的体系结构的主要发展趋势,以及这种趋势如何影响未来的大规模并行编 程给出了一个简单的调查结果。我们预言在未来10年内,大规模并行计算的优势会使它变
第1章引言15 成最热门的领域之一。 参考文献与课外阅读 1.Hwu,W.W.,Keutzer,K.,&Mattson,T.(2008).The Concurrency Challenge.IEEE Design and Test of Computers,July/August,312-320 2.Khronos Group.(2009).The OpenCL Specification Version 1.0.Beaverton,OR:Khronos Group.(http://www.khronos.org/registry/cl/specs/opencl-1.0.29.pdf). 3.Mattson,T.G.,Sanders,B.A.,&Massingill,B.L.(2004).Patterns of Parallel Programming. Upper Saddle River,NJ:Addison-Wesley. 4.Message Passing Interface Forum.(2009).MPI:A Message-Passing Interface Standard. Version 2.2.Knoxville:University of Tennessee.(http://www.mpiforum.org/docs/mpi-2.2/ mpi22-report.pdf). 5.NVIDIA.(2007).CUDA Programming Guide.Santa Clara,CA:NVIDIA Corp.OpenMP 6.Architecture Review Board.(2005).OpenMP Application Program Interface.(http://www. openmp.org/mp-documents/spec25.pdf). 7.Sutter,H.,Larus,J.(2005).Software and the Concurrency Revolution.ACM Oueue,3(7), 5462. 8.von Neumann,J.(1945).First Draft of a Report on the EDVAC.Contract No.W-670-ORD- 4926,U.S.Army Ordnance Department and University of Pennsylvania(reproduced in H.H. Goldstine,Ed.,The Computer:From Pascal to von Neumann,Princeton University Press, Princeton,NJ,1972). 9.Wing,J.(2006).Computational Thinking.Communications of the ACM,49(3),33~35