如果我希望我的代码将来在千万亿级机器上运行,我应该投资哪些编程范式?

计算科学 百亿亿次 编程范式 高性能计算
2021-12-22 19:54:50

从对 500 强的调查中可以清楚地看出,该行业的处理核心正呈指数级增长最大的超级计算机都使用 MPI 进行节点之间的通信,尽管节点上并行性似乎没有明显的趋势,使用最简单(但不一定是最有效)的方法将单个 MPI 进程映射到每个内核,自动来自编译器、OpenMP、pthreads、CUDA、Cilk 和 OpenCL 的并行化。

我是一组维护和开发代码的科学家之一,该代码有可能用于世界上一些最大的超级计算机。假设开发人员的时间有限,我该如何应对未来的挑战,以便能够利用世界上最强大机器的性能?我应该对工艺互连架构做出哪些假设?当我们进入众核时代时,哪些范式会受到影响?分区全球地址空间语言是否会在 PB 级机器上“投入生产”?

4个回答

历史的角度

真的不可能说未来新的范式会是什么样子,例如一个好的历史视角我建议阅读 Ken Kennedy 的HPF 的兴衰Kennedy 介绍了两种新兴模式,MPI 与智能编译器,并详细说明了 MPI 如何拥有适量的早期采用者和主导的灵活性。HPF 最终解决了它的问题,但为时已晚。

在许多方面,PGAS 和 OpenMP 等几种范例都遵循相同的 HPF 趋势。早期的代码不够灵活,无法很好地使用,并且在桌面上留下了很多性能。但是,不必编写并行算法的每一部分的承诺是一个有吸引力的目标。所以对新车型的追求一直在追求。


硬件趋势明显

现在,人们经常提到 MPI 的成功与它如何对其运行的硬件进行建模密切相关。大致每个节点都有几个进程,并且将消息传递到本地点对点或通过协调的集体操作很容易在集群空间中完成。正因为如此,我不相信任何给出不紧跟新硬件趋势的范式的人,实际上我是通过Vivak Sarakar的工作确信这一观点的。

与此保持一致的是,以下三个趋势显然在新架构中取得了进展。让我明确一点,现在有十二种不同的架构在 HPC 中销售。这比不到 5 年前仅支持 x86 有所上升,因此未来几天将看到许多以不同且有趣的方式使用硬件的机会

  • 特殊用途芯片:想想像加速器这样的大型矢量单元(Nvidia 的 Bill Dally 支持的观点)
  • 低功耗芯片:基于 ARM 的集群(以适应功耗预算)
  • 芯片的平铺:考虑不同规格的芯片的平铺(Avant Argwal的作品)

当前型号

当前模型实际上是 3 级深度。虽然有很多代码很好地使用了其中两个级别,但使用这三个级别的代码并不多。我相信,要首先达到 exascale,需要投资确定您的代码是否可以在所有三个级别上运行。这可能是顺应当前趋势进行迭代的最安全路径。

让我迭代模型以及它们将如何根据预测的新硬件视图进行更改。

分散式

分布式级别的播放器主要属于 MPI 和 PGAS 语言。MPI 现在是一个明显的赢家,但是像 UPC 和 Chapel 这样的 PGAS 语言正在进入这个领域。一个很好的迹象是 HPC 基准挑战。PGAS 语言提供了非常优雅的基准测试实现。

这里最有趣的一点是,虽然这个模型目前只在节点级别工作,但它将成为 Tiled 架构节点内的一个重要模型。一个迹象是英特尔 SCC 芯片,它从根本上就像一个分布式系统。SCC 团队创建了自己的 MPI 实现,许多团队成功地将社区库移植到此架构。

但老实说,PGAS 确实有一个进入这个领域的好故事。您真的要对 MPI 节点间进行编程,然后必须在节点内执行相同的技巧吗?这些平铺架构的一个重要问题是它们在芯片上具有不同的时钟速度以及内存带宽的主要差异,因此高性能代码必须考虑到这一点。

节点共享内存

在这里,我们看到 MPI 通常“足够好”,但 PThreads(以及从 PThreads 派生的库,例如 Intel Parallel Building Blocks)和 OpenMP 仍然经常使用。普遍的观点是,当有足够多的共享内存线程时,MPI 的套接字模型会为 RPC 崩溃,或者您需要在核心上运行更轻量的进程。您已经可以看到 IBM Bluegene 系统存在共享内存 MPI 问题的迹象。

正如 Matt 评论的那样,计算密集型代码的最大性能提升是串行代码的矢量化。虽然许多人认为这在加速器中是正确的,但它对于节点机器也很重要。我相信 Westmere 有一个 4 宽的 FPU,因此如果没有矢量化,一个人只能获得四分之一的翻牌。

虽然我没有看到当前的 OpenMP 很好地进入了这个领域,但低功耗或平铺芯片有一个地方可以使用更多的轻线程。OpenMP 难以描述数据流的工作原理,并且随着使用的线程越来越多,我只看到这种趋势变得更加夸张,只需看看如何使用 OpenMP 进行正确预取的示例。

课程级别足够高的 OpenMP 和 PThreads 都可以利用必要的矢量化来获得良好的峰值百分比,但这样做需要以自然矢量化的方式分解您的算法。

协处理器

最后,协处理器(GPU、MIC、Cell加速器)的出现已经站稳脚跟。越来越清楚的是,没有它们,通往 exascale 的道路将是不完整的。在 SC11,每位贝尔奖的参赛者都非常有效地使用它们来达到低 petaflops。虽然 CUDA 和 OpenCL 主导了当前市场,但我希望 OpenACC 和 PGAS 编译器进入该领域。

现在要达到 exascale,一个建议是将低功率芯片与许多协处理器耦合。这将很好地杀死当前堆栈的中间层,并使用管理主芯片上的决策问题的代码并将工作转移到协处理器。这意味着要使代码非常有效地工作,人们必须根据内核(或小码)重新考虑算法,即无分支指令级并行片段。据我所知,这种演变的解决方案非常开放。


这对应用程序开发人员有何影响

现在来回答你的问题。如果你想保护自己免受即将到来的百亿亿级机器的复杂性,你应该做一些事情:

  • 开发您的算法以适应至少三个级别的并行层次结构。
  • 根据可以在层次结构之间移动的内核来设计您的算法。
  • 放松您对任何顺序流程的需求,所有这些效果都将异步发生,因为同步执行是不可能的。

如果您想在今天表现出色,MPI + CUDA/OpenCL 就足够了,但 UPC 已经到了那里,所以花几天时间学习它不是一个坏主意。OpenMP 可以帮助您入门,但一旦需要重构代码就会导致问题。PThreads 需要将您的代码完全重写为它的风格。这使得 MPI + CUDA/OpenCL 成为当前最好的模型。


这里没有讨论什么

虽然所有这些关于 exascale 的讨论都很好,但这里没有真正讨论的是将数据输入和输出机器。尽管内存系统取得了许多进步,但我们在商品集群中看不到它们(太贵了)。现在数据密集型计算正在成为所有超级计算会议的一大焦点,势必会有更大的运动进入高内存带宽空间。

这带来了可能发生的另一个趋势(如果合适的资助机构参与其中)。对于所需的计算类型,机器将变得越来越专业。我们已经看到 NSF 资助了“数据密集型”机器,但这些机器与 2019 年的百亿亿次大挑战赛处于不同的轨道上。

这比预期的要长,请在评论中需要它们的地方提供参考

我会在这个帖子上尝试比我尊敬的一些同事更短的答案;-)

我对所有学生的信息始终是,开发人员的时间比 CPU 时间更有价值。这意味着,如果您有时间以 80% 的效率将 100% 的代码转换为在大型机器上运行——使用高级方法——那么你比使用耗时的低级方法要好这种方法可以让您在 20% 的代码上实现 100% 的效率。因此,我是高级库的忠实粉丝。在这方面我最喜欢的是线程构建块 (TBB),因为它允许我在最外层循环和高层次上查看算法。它还可以做所有你可能想用 pthread 做的事情,而不必处理操作系统功能等。我不喜欢查看最内层循环的方法,因为这是利用节点内并行资源的错误级别 - - 所以没有 OpenMP,

我不能与权威谈论 OpenCL、CUDA 等。

让我们从讨论节点内代码(不涉及互连的计算)的策略开始,因为我认为 MPI 是节点间代码的不错选择。我认为谈论少于 100 个内核的节点是没有意义的,因此至少是当前的 GPU 或 MIC。

事实上,仅 pthreads 无法让您在任何现代芯片上获得最大性能,因为您必须利用向量单元(自第一个 Cray 以来就是如此)。在 Intel 和 AMD 上,您可以使用内在函数,但它们不是可移植的,而且在我看来很笨重。CUDA 和 OpenCL 在库中内置了矢量化功能,可以轻松获得最佳性能。我知道的所有新硬件都有这个向量要求,所以任何解决方案都应该考虑到这一点。对我来说,CUDA/OpenCL 是当前的发展方向。

接下来,所有这些机器都将是 NUMA,它更难编程,但我认为内核策略有效。您将工作和数据分成小单元。这些可能会自动安排,就像当前在 CUDA 和 OpenCL 中发生的那样,但您可以指定依赖项。对于适合流范式的问题,这种分块也可以自动完成。英特尔 TBB 可以做到这一点,但我更喜欢以ThrustCusp为代表的更高级别的库方法,它可以针对 CUDA 或(很快)TBB。

之前发布的答案非常好,但主要集中在节点架构上,我认为这反映了这样一个事实,即在大多数情况下,MPI 通常被认为足以作为节点间编程模型,并且我们正在努力解决节点内并行性。

以下是我试图以相对有限的方式回答两个尚未回答或回答的问题:

我应该对工艺互连架构做出哪些假设?

我将考虑网络的三个属性:

  1. 潜伏,
  2. 带宽,和
  3. 并发。

延迟与频率成反比。我们知道频率缩放已经停滞不前。因此,可以得出结论,延迟不太可能在未来显着减少。Blue Gene/Q 上的 MPI send-recv 延迟约为 2 us,对应于 3200 个周期。超过一半的延迟是软件,但其中很大一部分是 MPI 标准要求的;广泛的调整可能会将延迟减少到接近 1 us,特别是如果可以断言不会使用 MPI 通配符。

无论如何,Blue Gene 和 Cray 系统上数据包注入的硬件延迟大约为 1 us。如果有的话,增加节点级别的并发性很难将这个数字保持在这么低的水平,但我乐观地认为,硬件设计人员会在可预见的未来找到将延迟控制在 5 us 以下的方法。

通过增加网络链接的数量,网络带宽可以得到微不足道的增加。然而,这只是故事的一部分。如果处理器无法以全带宽驱动网络,则将 1000 个出站链路放在一个节点上,并且无法使用它们。例如,就注入带宽而言,某些超级计算机的瓶颈在于总线(例如 HyperTransport)而不是网络。

网络带宽没有基本限制,只有实际限制。带宽需要金钱和电力。在开发未来系统时,系统设计人员必须考虑网络带宽和机器其他部分之间的权衡。许多代码不受网络带宽限制,因此我们似乎不太可能在未来看到每个连接带宽显着增加的机器。但是,每个节点的带宽应该与计算能力成正比增加,因此每个节点需要多个连接才能扩展。

在正式模型中经常被忽视的网络的第三个属性是一次可以发送多少条消息。对于大多数用途而言,拥有一个具有 1 ns 延迟和/或 1 TB/s 带宽且一次只能发送 1 条消息的网络将是完全没有用的。重要的是能够同时从大量线程发送大量消息,并且网络不会因争用而崩溃。Cray 和 Blue Gene 系统现在都实现了超过 1 MMPS(每秒百万条消息)。我不记得确切的数字,但两者都能够通过小消息实现峰值带宽的很大一部分。理想的网络可能能够使用任何大小的消息达到峰值带宽,但由于数据包标头和相关的簿记开销,这在实践中是不可能的。然而,

这是一个不完整且不完美的答案。欢迎其他人尝试改进它或提出我应该改进的建议。

分区全球地址空间语言是否会在 PB 级机器上“投入生产”?

Cray XE、XK 和 XC 系统具有生产质量的 UPC 和 CAF 编译器。Blue Gene 系统可以与 XLUPC 和 XLCAF 一起交付,但没有人要求这样做,因此没有交付。PERCS 拥有生产级 XLUPC 和 XLCAF 编译器,但没有可供科学界使用的大规模安装。

Coarrays 是 Fortran 2008 的一部分,尽管 Intel 和 GNU Fortran 中的实现还不是高质量的。英特尔的实现被认为可以工作,但也很慢(PGAS12 上有一篇关于它的论文)。

至于 PGAS 编程模型(因为编程模型 - 不是编程语言 - 是原始问题的主题),全局数组库在许多情况下是生产质量的合理近似值。作为运行时,它不如 MPI 强大,但 MPI 在实现质量方面非常独特。ARMCI 的 ARMCI-MPI 实现使全局数组更加稳定,尽管在某些情况下速度较慢。

使用 MPI-3 RMA 以生产质量的方式实现 PGAS 风格的构造相对容易。如果有人对此提出新问题,我很乐意回答。