祝贺 OpenMP 成立 20 周年
让 C/C++ 和 Fortran 程序员能够轻松进行并行编程——并提供通往百亿亿次计算的软件路径
点击此处注册并下载免费的 Intel® Parallel Studio XE 30天试用版
Rob Farber,全球技术顾问,TechEnablement
1997 年 10 月,OpenMP* 架构审查委员会 (ARB) 发布了 OpenMP Fortran 规范的 v1.0 版本,C/C++ 规范几乎一年后才发布。当时,世界上最快的超级计算机 ASCI Red,其计算节点搭载了两颗 200 MHz 的 Intel® Pentium® Pro 处理器。(是的,当时领导级的超级计算认为单核 200 MHz 的 Intel Pentium 处理器就很快了。)ASCI Red 的造价为 4600 万美元(按今天的购买力约合 6800 万美元),是第一台在 TOP500 LINPACK 基准测试中达到每秒万亿次浮点运算的超级计算机。它也是第一台消耗兆瓦功率的超级计算机——预示着未来的趋势。相比之下,现代双路 Intel® Xeon® 处理器 v4 系列在每秒万亿次浮点计算能力和功耗方面都非常划算。
极端规模技术研究中心(Center for Research in Extreme Scale Technologies)主任 Thomas Sterling 博士表示:“OpenMP 提供了一种单一系统编程和执行的愿景,强调简洁性和统一性。它挑战系统软件的生产者去处理异步、延迟和控制开销,同时鼓励未来的硬件系统设计者在百亿亿次时代实现用户生产力和性能可移植性。过去二十年取得了显著成就,这将引领未来 20 年的可扩展计算。”
OpenMP:一项具有前瞻性、以开发者为驱动的努力
OpenMP 计划是由开发者社区推动的。当时,人们越来越希望有一个标准,程序员可以可靠地使用它在不同的并行共享内存平台之间迁移代码。
在 OpenMP 出现之前,程序员必须显式使用线程模型,如 pthreads,或分布式框架,如 MPI,来创建并行代码。(第一个 MPI 标准于 1994 年完成。)只需添加一个 OpenMP pragma 即可在共享内存模型中利用并行性的便利性,这在当时是革命性的。但是,那时线程计算模型的兴趣有限,因为单线程处理器集群主导着高性能计算的世界。在某些硬件平台上,可以购买额外的插入式 CPU 来提供基于硬件的多线程性能。但总的来说,线程被认为是利用操作系统时间片模拟异步行为的软件技巧,而不是实现可扩展并行性能的途径。当时,关于线程的讨论更多地集中在使用重量级线程(例如,通过 fork/join 创建的进程),而不是共享内存的轻量级线程。节点内的硬件并行性仅限于双核或四核处理器系统,因此 OpenMP 的扩展性当时不成问题。
因此,1997 年的 OpenMP 规范极具前瞻性,因为分布式内存 MPI 计算是通往并行化的“主要途径”。基本上,通过网络连接大量机器更便宜、更容易。在 Dennard 缩放定律适用的时代,通过添加 MPI 节点或购买具有更高时钟速率处理器的机器来运行串行软件,可以实现更快的应用程序性能。因此,当时的主要进展来自于使用商品现成 (COTS) 硬件构建集群,这主导了 并行计算的世界(图 1)。例如,1998 年最初的 Beowulf 操作指南解释说,“Beowulf 是一种将计算机集群化以形成一个并行虚拟超级计算机的技术”,“它的行为更像一台机器而不是许多工作站。”当时并没有大规模的科学或商业需求来支持多核处理器——因此,多线程并行计算更像是一个非常有趣的 HPC 项目,而不是主流的编程模型。图 1 中短暂出现的大规模并行单指令多数据 (SIMD) 的插曲持续时间很短,基本上随着 Thinking Machines Corporation 的消亡而消失,该公司制造了 SIMD 架构 CM-2 超级计算机以及后来的 CM-5 MIMD(多指令多数据)大规模并行处理器 (MPP) 超级计算机。SGI Challenge 是那个时代 SMP(在此上下文中指共享内存多处理器)的一个例子。
OpenMP 崭露头角:Dennard 缩放定律失效与多核的崛起
在 2005 年至 2007 年间,Dennard 缩放定律失效变得显而易见,我们开始看到第一批现代多核处理器。由于无法通过提高时钟速率来显著提高性能,制造商不得不开始增加处理器核心数量来产生显著的性能提升(并提供升级的理由)。这打破了旧有的舒适状态,即通过时钟速率的提高,代码会在下一代硬件上自动运行得更快。因此,人们开始认真研究利用线程计算作为提高应用程序性能的手段。尽管如此,大多数应用程序仍然通过在多处理器上为每个核心运行一个串行 MPI 进程来利用并行性。
在 2007 年至 2008 年期间,多核处理器开始主导性能格局,如图 2 所示,这是 TOP500 组织提供的性能份额图。您可以清楚地看到,此后的趋势一直是增加核心数量。
OpenMP 代码现代化
核心数量的增加使 OpenMP 和 MPI 程序都能受益于更大的并行性。但向量并行性的复兴,加上高核心数处理器,确实将 OpenMP 推向了主流地位。
许多旧应用程序之所以采用每个处理器核心一个 MPI 进程的模式,是因为在编写它们时,并行性是 COTS 硬件上获得性能的途径。这并不是说向量化没有被利用——尤其是在 HPC 代码中——而是为了说明 COTS 集群中使用的处理器的小向量宽度限制了性能收益。此外,对向量单元进行编程很困难。因此,许多程序员继续依赖增加 MPI 并行性来获得更高的应用程序性能。在每个 MPI 进程内部运行的向量化循环带来的任何好处都是一个不错的额外好处。
从 2006 年左右开始,SIMD 和数据并行编程的复苏表明,重写旧代码以利用硬件线程并行性可以在广泛的应用和计算领域带来显著的性能提升。
随着人们意识到能效是通往 PetaScale——以及最终 ExaScale——计算机的关键瓶颈,这一趋势加速了。Green500 榜单于 2007 年首次亮相,标志着大规模计算中“不惜一切代价追求性能”时代的结束。
OpenMP 突然处于有利位置,可以利用对能效计算和数据并行性的关注。简而言之,CPU 是通用的 MIMD 设备,可以高效地运行 SIMD 代码。更好的是,SIMD 代码可以很好地映射到硬件向量单元。与此同时,基于 MIMD 的任务并行性只需一个循环结构即可实现。
为了提高性能和能效,x86 ISA(指令集架构)中不断添加更宽的向量指令。其他 ISA 也在进行类似的努力。简而言之,硬件向量单元在芯片的硅片上占用空间相对较小,但它们可以提供非常节能的浮点性能。因此,通用处理器的浮点能力急剧增加,高核心数(或多核)向量并行处理器的时代应运而生。例如,Intel Xeon 和 Intel® Xeon Phi™ 处理器就属于这一类。
随着人们意识到每个核心一个 MPI 进程的编程模型效率低下,因为它未能充分利用 SIMD、数据并行和向量编程的性能优势,代码现代化成了一个热门词。例如,有效地利用最新一代硬件上的 AVX-512 向量指令,可以将双精度代码的应用性能提高 8 倍,单精度代码提高 16 倍。许多编程项目已经或正在切换到 OpenMP/MPI 混合模型,以充分利用 MPI 和 OpenMP 的优势。由此产生的性能提升可以是核心数量和向量性能的乘积,如图 3 所示。事实上,最新的 Intel Xeon Phi 处理器每个核心有两个 AVX-512 向量单元。
OpenMP:现状
OpenMP 标准认识到 SIMD 编程的重要性,并在 2013 年 10 月的 OpenMP 4.0 标准中添加了 SIMD 子句。OpenMP 4.0 规范还添加了其他子句,以便现在也支持协处理器和 GPU 等加速器的卸载模式编程。OpenMP 将继续发展并适应不断变化的硬件格局。
面向 Exascale 时代的 OpenMP
展望 Exascale 的未来,功耗是关键。Exascale 计算架构的趋势是将节能串行核心与并行硬件相结合——本质上是 Amdahl 定律的硬件实现。NERSC 指出,最新的 Cori 超级计算机首次让用户在一个领导级超级计算机上运行程序,如果不对代码进行任何修改,程序运行速度会变慢。这就是功耗效率提高所带来的不可避免的后果,因为 Exascale 超级计算机的节能串行核心需要更多时间来运行顺序代码。这一趋势可能会蔓延到数据中心,因为功耗对底线和利润至关重要,但预计 5G 将使数据量增加高达 1000 倍(来源:Forbes)。
令人欣慰的是,OpenMP 现在已经是一个久经考验的可靠技术,它在提供性能的同时,仍然实现了最初的设计目标——为程序员提供一个可以可靠地在不同并行共享内存平台之间迁移代码的标准。性能加上可移植性:多么美好的组合。Rob Farber 是一位全球技术顾问和作家,在 HPC 领域拥有丰富的经验。他积极倡导可移植、并行、高性能的编程。您可以通过 info@techenablement.com 与他联系。