序
并行编程现在是主流。从笔记本计算机到世界最大的超级计算机,从手机到高端医疗设备,现代计算系统集成了架构并行性,以便为其应用程序提供高性能。当多核计算机成为标准时,几乎每个拥有笔记本计算机的人都能接触到并行计算。然而,为了使应用程序更好地利用架构并行性,通常我们要改进应用程序,以展现其内在的并发性。无论是创建新的并行应用程序,还是为已有的应用程序引入并行性,如今的应用程序开发者能使用新的高级并行语言,或者运用已有的串行语言的并行扩展,或者使用库调用来满足需求。为了获得高性能、可移植性和跨并行平台的性能可移植性,之前从未有过这么多关于并行语言的活跃开发和如此多的运用崭新方法的试验。
有很多书籍介绍了并行编程语言特性、运用这些特性的算法以及应用程序开发人员部署算法的经验。但关于并行编程语言特性的实现方式,以及如何为并行编程接口构建高质量编译器和运行时系统的书籍却很少。当编译器翻译由高级并行编程语言编写的程序时,必须得到运行时系统的支持。运行时系统负责管理执行过程中的计算资源、为计算资源分配任务、实现必要的同步等。高级编程接口的采用在很大程度上取决于用户体验的质量,所以必须精心设计这些接口以及它们之间的交互。
有些运行时系统要持续地为运行在多核平台上的应用程序提供高性能。在开发这种运行时系统的时候,不仅要满足基本的实现需求,还要确保运行时系统各组件都是高效的和经过精心设计的。开发人员必须为关键功能(例如同步障)选用可扩展算法,而且在实现各种算法时,要注意避开执行过程中潜在的性能问题,例如缓存数据伪共享。开发人员要提供处理空闲线程的合理策略,还要优化并行循环的性能。如果可能,他们还要设计利用架构特性的方法。
本书着重讲解构建高性能并行运行时的实践方法。考虑到设计良好的运行时对于并行编程模型的重要性,这本书算得上是姗姗来迟。最前沿的、执行并行程序代码的运行时系统的构建过程,涉及很多设计与实现方面的决策。作者深入探讨了这些决策,还提供了大量示例,并论述了一些现实中的编译器和运行时。书中描述了当前计算机架构的重要细节,以便引出并行编程的需求和后续技术。例如,我们会学习现代多核缓存管理策略的细节及其对性能的影响,以及如何用原子和事务内存来支持同步。
作者谈及了通用设计的注意事项,也讨论了现代架构和并行编程特性对运行时开发人员的影响。他们详细解释了编译器和运行时如何协作实现OpenMP标准和Intel线程构建模块(Threading Building Block,TBB)。虽然这些内容出色地解释了编译器与运行时之间的交互方式,但本书远不止于此。它还简要介绍了编译器工作原理,并描述了编译器实现lambda函数的方式,这种lambda函数可简化在创建TBB任务时所需的代码。OpenMP有几个不同的构造,应用程序开发人员能借助它们在代码中表达并行性。作者还概述了运行时系统的实现,而非简单地说明运行时系统的作用。他们详细解释了程序执行之前的编译过程,以及运行时各组件的细节,并出色地介绍了其他高级并行编程语言特性的实现。
目前存在各种不同的同步机制和算法来实现并行运行时系统。在本书中,我们会遇到对同步硬件支持、常用同步构造、构造的实现策略的全面且实用的讨论。作者论述了实现锁的过程中的非凡挑战,讨论了一个长期存在的问题:如何处理处于等待状态的线程。
作为指明并行性的一种方法,任务变得极其流行。任务的创建和执行相分离,从这个方面来说,任务本质上是动态的。相比于其他的语言构造,运行时监督任务执行的各个方面,包括处理与任务相对顺序相关的所有需求,以及将任务排队以便执行。书中对任务的运行时支持的讨论,不仅包含了任务池(或队列)的设计,还考虑了任务依赖性、调度、任务窃取和更多的同步方法。
随着平台在异构性及规模方面的不断增长,运行时在实现中的角色越来越重要。如今的并行运行时,不再“仅仅是”编译器的支持基础设施,它还必须主动管理跨越多个NUMA域的工作负载,可能还要决定应在何处执行特定代码,或者何时尝试窃取任务。未来的运行时应该还会更加强大,它可能会通过调整代码的执行细节来应对执行环境或者程序自身计算需求的变化。
我相信本书对于系统研究人员和从业者来说非常有价值。它提供了大量关于现代运行时系统主要功能的信息,还清晰地解释了实际实现细节和潜在陷阱。OpenMP运行时的代码也可供读者进行试验。本书还包含了充足的关于多核平台的背景知识,以确保初学者也能理解书中的内容。这些也是对于此类系统实际工作的介绍。以上所有内容,以及非常多的示例与讲解,都囊括在这本丰富、有趣且与时俱进的书中。尽管某些主题比较有深度,但本书整体上易于理解。本书作者都是领域内活跃的从业者,在并行编程库、语言、并行运行时的设计和实现方面拥有丰富的经验。对于运用并行系统时可能遇到的挑战与陷阱,以及在现实中软件开发工作的工程方面,他们具有深刻体会。
几乎从OpenMP首次面向公众发布以来,我就一直参与它对编译器的支持的开发。而且我敏锐地意识到了精心设计运行时系统的重要性。任何OpenMP实现中的关键要素都是高质量运行时系统。这种运行时系统的开发者需要成功克服无数个由多核平台带来的性能挑战。这项工作需要高超精湛的工程设计,需要对任务本质及其内在挑战有深刻理解,还要有可靠的解决策略。这种深刻理解以及完成这项工作所需的技术,正是这本书所提供的。
我极力推荐这本书!
Barbara Chapman
纽约州立大学石溪分校
布鲁克海文国家实验室