try ai
科普
编辑
分享
反馈
  • 并行性能扩展:原理、瓶颈与应用

并行性能扩展:原理、瓶颈与应用

SciencePedia玻尔百科
核心要点
  • 强扩展旨在更快地解决一个固定规模的问题,但随着通信开销在计算时间中占据主导地位,效率不可避免地会下降。
  • 弱扩展通过使用更多资源来处理一个按比例增大的问题,测试算法在恒定时间内处理不断增大的问题规模的能力。
  • 通信(一种“表面积”成本)与计算(一项“体积”任务)之比是限制并行可扩展性的一个根本瓶颈。
  • 算法创新,例如先进的预处理器或在 Roofline 模型指导下的内存感知优化,对于克服扩展性限制至关重要。

引言

并行计算的前景是巨大的:利用一百万个处理器来解决规模大一百万倍或速度快一百万倍的问题。然而,任何尝试过的人都知道,这个梦想常常与严酷的现实相冲突。仅仅增加更多的处理器并不能保证成比例的加速;事实上,有时甚至会使情况变得更糟。这种差异源于任何协作努力中固有的协调、通信和竞争等基本成本。为什么会发生这种情况?我们又该如何设计能够高效扩展的系统呢?

本文全面概述了并行性能扩展,揭示了支配大规模计算效率的原则。它旨在弥合高性能计算的理论前景与实际挑战之间的差距。

首先,在​​原理与机制​​部分,我们将剖析强扩展和弱扩展这两个核心概念,它们是我们衡量性能的两个主要视角。我们将探讨延迟的构成,从计算与通信之间的几何关系,到阿姆达尔定律(Amdahl's Law)所施加的理论限制。接着,​​应用与跨学科联系​​部分将展示这些原理如何在现实世界的科学发现中得以体现。我们将穿越不同的领域,从模拟星系、建立燃烧模型到设计新型电池,揭示算法选择和对底层物理的深刻理解是如何成为释放真正并行性能的关键。

原理与机制

想象你有一个宏大的项目:建造一座巨大而复杂的房子。独自一人可能需要一年时间。一个朋友建议:“为什么不再雇佣 364 个人呢?有 365 个工人,这项工作应该一天就能完成!”我们凭直觉就知道这很荒谬。工人们会互相碰撞,等待材料,花在交谈和协调上的时间比实际建造还要多。一天建成房子的梦想被通信、协调和共享资源争用这些平凡的现实所击碎。

这个简单的寓言抓住了并行计算的精髓。梦想是用一百万个处理器将问题解决速度提高一百万倍。现实则是一场与合作固有成本进行的迷人而优美的斗争。要理解我们如何高效地建造这些计算“房屋”,我们必须首先理解支配它们的基本原理。

并行之路:更快还是更大?

当我们决定使用多个处理器时,通常是在追求两个目标之一。这两种追求定义了我们衡量并行性能的主要方式。

第一个目标是​​更快​​地解决一个固定规模的问题。这被称为​​强扩展(strong scaling)​​。假设我们正在模拟一场海啸在太平洋中的传播路径。海洋的大小和我们网格的期望分辨率是固定的。我们的目标是尽快得到预报。如果我们将处理器数量 PPP 增加一倍,我们希望将求解时间 TPT_PTP​ 减半。我们用​​加速比(speedup)​​来衡量这一点,即 S(P)=T1/TPS(P) = T_1 / T_PS(P)=T1​/TP​,其中 T1T_1T1​ 是在单个处理器上的运行时间。在理想情况下,S(P)=PS(P) = PS(P)=P。

当然,现实永远不是理想的。我们定义​​并行效率(parallel efficiency)​​,E(P)=S(P)/PE(P) = S(P) / PE(P)=S(P)/P,作为衡量我们距离这种完美加速比有多近的指标。效率为 111(或 100%100\%100%)是理想情况,但现实世界中的值总是更低。为什么?因为总时间不仅包括计算,还包括计算和通信的总和。随着我们增加更多处理器,每个处理器上的计算工作量减少,但通信开销通常不会同样迅速地减少,甚至可能增加。这种开销——即用于协调的时间——在总时间中所占的比例越来越大,导致效率下降。

第二个目标是用更多的资源解决一个​​更大​​的问题。这就是​​弱扩展(weak scaling)​​。想象一下,我们现在是分子生物学家,正在模拟蛋白质的行为。有了更多的处理器,我们不仅仅想更快地模拟同一个小蛋白质;我们希望在最初用于小蛋白质的相同时间内,模拟一个更大的分子复合物,或者一个由许多蛋白质组成的更大系统。在弱扩展中,我们使总问题规模 NNN 与处理器数量 PPP 成正比增加,从而保持每个处理器的负载恒定。理想的结果是,无论我们使用多少处理器,求解时间都保持不变。我们用我们的资源来扩展我们的雄心。一种很好的思考方式是​​等粒度扩展(isogranular scaling)​​,即我们可能扩展模拟宇宙的体积,同时保持模拟网格的分辨率或“粒度”不变。

在实践中,弱扩展的性能也会下降。虽然根据设计,每个处理器的计算工作量是恒定的,但通信成本仍可能随着所涉及的处理器总数的增加而增长。一个全局操作,比如计算系统的总能量,可能需要每个处理器与所有其他处理器通信,这个过程会随着“委员会规模” PPP 的增大而变慢。

延迟的剖析:一个关于表面与体积的故事

要真正理解并行效率为何如此难以捉摸,我们必须剖析开销的本质。根本原因在于一个简单的几何原理:表面积和体积之间的关系。

当我们把一个大的计算问题分解成小块,让每个处理器处理一部分——这种技术称为​​区域分解(domain decomposition)​​——每个处理器需要做的计算量与其分块的“体积”有关。然而,为了计算其分块边缘发生的情况,处理器需要来自其邻居的信息。这些信息必须跨越分隔子区域的“表面”进行通信。

考虑一个三维模拟,模拟热量在一块金属中流动的情况,该金属块被离散化为一个单元网格。我们可以将这个金属块在我们的处理器之间进行划分。我们可以像切面包一样将其切成薄片,或者将其切成长而细的“铅笔状”条,甚至切成小立方体。在每种情况下,处理器都计算其体积内所有单元的热流。但要做到这一点,它需要来自边界另一侧的光环单元(halo cells)的温度值,这些单元属于它的邻居。它必须暂停计算,发送消息来获取这些数据。它需要交换的数据量与其子区域的表面积成正比。

问题就在这里:当我们在强扩展中使用更多处理器时,每个子区域的体积收缩得远比其表面积快。对于一个边长为 LLL 的立方体,其体积为 L3L^3L3,表面积为 6L26L^26L2。表面积与体积之比为 6/L6/L6/L。随着我们划分问题且 LLL 变小,这个比率会变大。处理器在通信(表面工作)上花费的时间比例越来越高,而在计算(体积工作)上花费的时间比例越来越低。

这个通信时间 TcommT_{comm}Tcomm​ 可以进一步分解。发送一条消息的时间可以建模为 Tmsg=α+β⋅mT_{msg} = \alpha + \beta \cdot mTmsg​=α+β⋅m,其中 mmm 是消息的大小(以字节为单位)。

  • β\betaβ 项代表​​带宽(bandwidth)​​。它是每字节数据的成本,与通信管道的“粗细”有关。这是我们问题中与表面积相关的部分。
  • α\alphaα 项代表​​延迟(latency)​​。它是一个固定的、每条消息的开销,就像打包、写地址和发送一封信所需的时间,无论信中包含一页还是二十页。

在许多情况下,尤其是在强扩展中,延迟是无声的杀手。随着我们添加越来越多的处理器,每个处理器的计算量可能会缩减到小于单条消息的延迟。处理器瞬间完成其微小的任务,然后就处于空闲状态,等待消息的到来。这道“延迟墙”是可扩展性的一个根本障碍。

情况甚至可能更糟。一些算法,如许多物理模拟中使用的快速傅里叶变换(FFT),不仅需要与直接邻居通信,还需要全局性的“全对全”(all-to-all)通信,即数据在处理器之间完全重排。在这些情况下,一个处理器需要发送的消息数量本身可能随着处理器数量 PPP 的增加而增加。这可能导致效率的灾难性下降,此时增加更多的处理器实际上会使问题的通信部分耗时更长。

收益递减法则

这些扩展性挑战不仅仅是学术上的好奇心;它们具有深远的实际和经济后果。那位相信云为他的大规模计算提供了“无限资源”的同事,将会大失所望。

首先,​​阿姆达尔定律(Amdahl's Law)​​为我们关于收益递减的直觉提供了形式化的表述。它指出,最大加速比受限于代码中固有串行(无法并行化)部分的比例。即使是一个很小的串行部分,比如说 1%1\%1%,也意味着即使使用一百万个处理器,你也永远无法获得超过 100 倍的加速比。通信开销通常就像一个串行组件,为性能设置了硬性限制。

其次,在现实世界中,资源不是免费的。云服务提供商按处理器小时收费。如果你将处理器数量加倍,但由于效率下降只获得了 1.5 倍的加速比,你的墙上时钟时间(wall-clock time)减少了,但你的总账单却增加了!在强扩展的某个点之后,你花的钱越来越多,而获得的速度回报却越来越少。这是并行效率低下的经济体现。

第三,是日益增长的能源问题。这不仅仅是关于时间和金钱,还关乎消耗的电力。求解能耗可以建模为处理器静态功率(即处理器仅开机就消耗的功率)和用于计算的动态功率的函数。一个简洁的模型揭示了能耗与并行效率直接相关:E∝(P0/u+c)E \propto (P_0/u + c)E∝(P0​/u+c),其中 uuu 是处理器利用率(作为效率的替代指标),P0P_0P0​ 是静态功率。较低的效率意味着更多的时间被浪费,这又意味着为得到相同答案消耗了更多的能量。在大型数据中心时代,高能效的扩展至关重要。

这引出了一个哲学观点。如果我们对一个简单的并行系统建模,我们通常会发现并行效率 E(P)E(P)E(P) 是处理器数量 PPP 的严格递减函数。因此,最大效率出现在 P=1P=1P=1 的时候!。但当然,并行计算的目标不是追求完美的效率,而是解决一个若非如此便无法解决的问题。我们总是在进行权衡,寻求一个“最佳点”,在这个点上我们以可接受的效率、金钱和能源成本实现了必要的性能。

智胜机器:算法突围

我们是否注定要与这些扩展定律进行一场必败的战斗?进步是否受限于我们网络电缆的速度?幸运的是,答案是否定的。性能上最深刻的突破往往不是来自更好的硬件,而是来自更智能的算法。

如果一个用于解决物理问题的迭代算法收敛缓慢,它就需要大量的步骤。每一步都涉及与邻居的通信。总通信量是巨大的,可扩展性很差。人们可能想归咎于网络。但真正的问题是解中全局、平滑误差模式的缓慢收敛。一个巧妙的解决方案是使用​​多级预处理器​​,例如粗网格有限差分法(Coarse Mesh Finite Difference, CMFD)。该方法在一个小得多、更粗糙的网格上求解问题的近似版本,从而有效地抑制了有问题的全局误差。然后,这个粗网格校正被用来加速在细网格上的收敛。通过大幅减少所需的细网格迭代次数,这种算法上的改变削减了总通信量,并显著提高了可扩展性。瓶颈不是通过蛮力,而是通过洞察力克服的。

另一条算法优化的路径是审视单个处理器上计算与内存访问之间的平衡。​​Roofline 模型​​为此提供了一个优美的可视化方法,它通过算法的“计算强度”(operational intensity)——即每从内存移动一个字节的数据所执行的浮点运算次数——来刻画算法。计算强度低的算法是“内存密集型”的,意味着它们因数据供给不足而处理器处于空闲状态。这些算法的可扩展性往往很差。有时,我们可以转换算法,例如通过即时重新计算某些值而不是从内存加载它们。这种“空间-时间权衡”提高了计算强度,使算法更偏向“计算密集型”,最终在并行化时更具可扩展性。

并行扩展的原理揭示了计算与通信之间、局部与全局之间一场复杂的舞蹈。它们不是任意的规则,而是几何与逻辑的深刻结果。它们定义了可能性的边界,但在这些边界之内,人类在设计新算法方面的创造力不断地找到方法去实现一度被认为不可能的事情,从而不断推动科学和发现的前沿。

应用与跨学科联系

在我们迄今的旅程中,我们已经探讨了并行性能的基本原理,即强扩展和弱扩展这两个孪生概念,它们在高性能计算的广阔海洋中充当着我们的指南针。但是,原理无论多么优雅,只有在现实世界中焕发生机时才能获得其真正的意义。我们为何要费尽周折地利用一百万个处理器协同工作的力量?这是因为宇宙是无限复杂的,要理解它,我们必须模拟它。现在,让我们开始一场穿越科学领域的巡礼,看看扩展的简单理念是如何从恒星的核心到电池的设计,成为现代发现的基石。

宏大挑战:模拟连续世界

想象一下,尝试预测天气,或者模拟流过新型飞机机翼的空气。流体的世界是一场由复杂的偏微分方程(PDE)控制的无缝、连续的运动之舞。要在计算机上模拟它,我们必须将这个连续的世界切分成一个由离散单元组成的精细网格。在很长一段时间里,我们网格的规模——以及我们模拟的保真度——都受限于单台计算机的能力。并行计算有望打破这一限制。通过将网格分布到数千个处理器上,我们可以处理规模超乎想象的问题。

但正如我们在对扩展原理的研究中所看到的,这种能力并非没有代价。例如,当我们模拟湍流以研究传热时,每个处理器处理其网格的一部分。但是一个区域中的流体需要知道其邻居在做什么。这需要通信,即处理器之间持续的“交谈”。在一个强扩展研究中,我们为一个固定规模的问题使用越来越多的处理器,希望工作能更快完成。起初确实如此。但很快,每个处理器工作量减少所节省的时间,就被日益增长的通信开销所吞噬。这就是阿姆达尔定律(Amdahl's Law)在实践中的教训:任务中总有一部分——通信、同步——是抗拒并行化的,这就为我们能实现的加速比设定了硬性限制。

现在,让我们加入一点火花。如果流体不仅仅在流动,还在燃烧呢?在计算燃烧学中,我们不仅要模拟流体动力学,还要模拟每个点上发生的复杂化学反应网络。这增加了巨大的计算负担。你可能会认为这会使扩展问题变得更糟。但在这里,我们遇到了一个美妙的悖论。通过使每个单元的计算更加密集(例如,通过使用包含数百种物质的更详细的化学模型),我们实际上可以改善并行可扩展性。原因非常直观:处理器现在忙于本地计算,以至于它们花在等待邻居消息上的时间比例变小了。我们改善了计算与通信之比。这揭示了一个深刻的联系:我们选择包含在模型中的物理原理,对模型能够多好地被并行化,有着直接且有时出人意料的影响。

同样的,在平衡计算与通信的这出戏剧在无数的学科中上演。无论是模拟电池电极复杂微结构中离子和电子的流动,还是模拟聚变反应堆中等离子体的行为,挑战都是相同的:在一个能捕捉到基本现象的尺度上求解支配我们物理世界的方程,同时还要控制住并行合作不可避免带来的开销。

粒子的舞蹈:从恒星到分子

并非所有自然现象都是连续场。自然界的许多部分是一场由离散粒子组成的宏大芭蕾舞。以宇宙本身为例。为了理解星系如何形成和演化,天体物理学家使用模拟,其中恒星和气体由数百万个通过引力和流体动力学相互作用的粒子来表示。在这里,我们的目标通常不是更快地解决一个固定规模的问题(强扩展),而是处理越来越大的问题。我们想要模拟宇宙中更大的一块区域,包含更多的星系。这就是弱扩展的领域:如果我们把处理器数量增加一倍,我们就把粒子数量增加一倍,并希望求解时间保持不变。

当然,这种情况很少发生。随着我们模拟的宇宙越来越大,一个处理器区域边缘附近的粒子仍然需要与下一个区域的粒子通信,而这种远距离通信的复杂性会增加。我们的弱扩展效率,作为衡量我们离理想状态有多近的指标,开始下降。然而,通过测量这种效率,我们获得了对模拟瓶颈的宝贵见解,指导我们创造出更具扩展性的算法。

让我们从宇宙尺度缩小到纳米尺度。在分子动力学中,我们模拟构成蛋白质和其他生物分子的原子之间错综复杂的舞蹈。目标是理解这些分子如何发挥功能、折叠和相互作用——这正是生命的机制。为了使这些模拟可行,一个常见的技巧是使用约束算法将原子间的化学键视为刚性棒。但在这里,一个看似微小的实现细节可能对性能产生巨大影响。

一种经典的算法 SHAKE 是顺序工作的。它调整一个键,然后是下一个,再下一个,不断迭代直到所有约束都满足。这就像一个人试图通过一次调整一个结来解开一张缠结的网。它能用,但速度慢且本质上难以并行化。如果一个键中的两个原子在不同的处理器上,就必须发送一条消息,而其顺序性会造成大规模的交通拥堵。一个更现代的算法 LINCS,将问题重新表述为矩阵和向量的语言。这使得校正可以以一种更加并行的方式计算,就像许多工人同时修复网的不同部分。在拥有数千个处理器的超级计算机上,两者之间的差异有如天壤之别。高度并行的 LINCS 算法扩展性极佳,而顺序执行的 SHAKE 则会陷入停顿。这是一个深刻的教训:我们物理模型的数学表述与其计算性能并非相互独立。算法的选择就是信息流动方式的选择,而这一选择可以决定一个模拟是否可行。

引擎室:求解方程的艺术

让我们揭开盖子,看看驱动这些庞大模拟的引擎。问题的核心常常是求解一个巨大的线性方程组,紧凑地写为 Ax=bA \mathbf{x} = \mathbf{b}Ax=b。对于一个有十亿个单元的问题,矩阵 AAA 可能有十亿行和十亿列。我们如何求解这个方程是影响并行性能最关键的因素之一。

迭代法,如共轭梯度算法,是一种流行的选择。它们的工作方式是从一个猜测值开始,然后逐步进行修正。然而,每个修正步骤通常需要一个“全局归约”(global reduction),比如点积,这相当于向整个系统提问。这就像对所有处理器进行点名。在少数处理器上,这很快。但在一百万个处理器上,它就成了主要瓶颈,因为从每个处理器收集一个数字的延迟限制了整体进度。

这就是*预处理(preconditioning)*的艺术所在。预处理器是一种近似求解器,它能引导主迭代法更快地趋向解。不同预处理器的并行性能差异巨大。不完全 LU(ILU)分解是一种经典方法,它涉及的三角求解是出了名的顺序执行——就像一个救火水桶队,一个处理器只有在它的邻居完成后才能行动。这种方法的可扩展性很差。

相比之下,像稀疏近似逆(Sparse Approximate Inverse, SPAI)这样的方法从一开始就是为并行而设计的。SPAI 预处理器的设置通常可以分解为数千个完全独立的问题,使其成为“易并行”(embarrassingly parallel)且高度可扩展的。然而,对于许多物理问题,目前的王者是代数多重网格(Algebraic Multigrid, AMG)。它是一种优美的分层方法,可以同时在多个尺度上求解问题,从粗糙的“全局”视图到精细的细节。这使得它在极少数迭代中找到解的效果令人难以置信。但这种强大功能也带来了复杂性;它的设置成本高昂,并且在单次迭代中的应用比简单的 SPAI 应用涉及更复杂的通信模式。

没有哪一种求解器是“最好”的。这是一个充满权衡的丰富领域。当我们需要为许多不同的右端项 b\mathbf{b}b 求解同一个方程组 Ax=bA \mathbf{x} = \mathbf{b}Ax=b 时(例如,在多种不同载荷下对一个结构进行建模),一个有趣的见解就出现了。在这种情况下,一个具有非常高昂的一次性设置成本的方法(如 SPAI 或 AMG)可能成为最终的赢家,因为这个成本在随后多次快速求解中被摊销了。

现代图景:新架构与更深刻的见解

计算世界在不断变化。我们已经从简单的 CPU 集群发展到混合架构,其中每个节点可能包含一个拥有数千个微小核心的强大图形处理单元(GPU),或者多个共享内存的 CPU,。这给我们的扩展挑战带来了新的层次:我们在一个节点内部有超快的通信,而在节点之间则有慢得多的通信。

这种硬件的演进迫使我们以一种更细致的方式思考性能,从而产生了像 Roofline 模型这样强大的概念,。Roofline 模型提出了一个简单而深刻的问题:你的程序性能是受限于处理器执行算术运算的速度,还是受限于从内存中获取数据的速度?对于大量的科学代码,尤其是那些涉及由偏微分方程离散化产生的稀疏矩阵的代码,答案是内存带宽。能够每秒执行数万亿次操作的处理器,却因数据供给不足而处于空闲状态。这一认识改变了一切。它告诉我们,让我们的算法在数据访问方面变得更“智能”,可能远比仅仅试图减少计算次数更为重要。

这导致了一种协同设计(co-design)的理念,即物理、算法和硬件架构被一同考虑。例如,在为流体动力学模拟划分区域时,一种幼稚的方法可能只是简单地将几何网格切成大小相等的部分。一种更智能的方法是让物理原理来指导划分。在梯度较高的区域,如边界层,数值耦合非常强。一个“智能”的划分器会识别到这一点,并避免切穿这些区域,因为它知道这样的切割会创建一条通信的“高速公路”,从而严重影响性能。相反,它会根据跨越切割面的估计物理通量来对切割进行加权,这个量与当地的库朗数(Courant number)有关。这是一个绝佳的例子,说明了深刻的物理洞察力如何直接带来更好的并行性能。

另一种并行:吞吐量的力量

最后,我们必须认识到,并非所有的并行计算都是为了更快地解决单一的、庞大的问题。考虑一下自动化电池设计的挑战。我们可能想测试数千种不同的材料组合或电极结构。每个模拟都是一个独立任务。在这里,目标不是最小化单个模拟的时间,而是最大化我们每天可以运行的模拟总数——即科学吞吐量。

强扩展和弱扩展的概念被巧妙地应用于这种“易并行”(embarrassingly parallel)的工作流。固定总作业数量,通过增加更多节点来更快地完成批处理,这是一种强扩展形式,其关键性能指标是总完工时间(makespan)。增加更多节点,并给每个节点分配一组新的作业来处理,这是一种弱扩展形式,其目标是使我们的科学产出与计算资源成比例地增加。即使在这里,作业调度和最终数据聚合的开销也会妨碍理想的扩展,但我们学到的基本原理仍然为我们量化成功提供了语言和度量标准。

从最宏大的科学挑战到工业设计的实际应用,并行扩展的原理是一种通用工具。它们不仅仅是衡量计算速度的标尺;它们还是一个镜头,通过它我们可以理解我们科学问题的结构、算法中信息流动的模式以及我们方法的基本限制。我们发现,对性能的追求与对更深层次理解的追求本身是密不可分的。