现代服务器级系统通常由多个多核芯片组合在一个系统中构建而成。每个芯片都有一个本地 DRAM(动态随机存取存储器)模块;它们一起被称为一个节点。节点通过高速互连连接,并且系统是完全一致的。这意味着,对于程序员来说是透明的,一个核心可以向其节点的本地内存以及其他节点的内存发出请求。关键的区别在于远程请求将花费更长的时间,因为它们会受到更长的线路延迟的影响,并且可能必须跳转多个跃点才能遍历互连。因此,内存访问时间的延迟是非均匀的,因为它取决于请求的来源和目的地。这种系统被称为 NUMA(非均匀内存访问)。
具有 NUMA 特征的系统早在 20 世纪 80 年代就已构建,并且随着硬件操作系统的发展,对 NUMA 的支持也在不断发展。现代 NUMA 系统与旧系统截然不同,因此我们必须重新审视我们对它们的假设,并重新思考如何构建 NUMA 感知操作系统。本文评估了代表性的现代 NUMA 系统的性能特征,描述了 Linux 中的 NUMA 特定功能,并提出了一种内存管理算法,该算法可显着减少内存访问时间并提高性能。
NUMA 系统由多个节点组成,每个节点包含系统 CPU 核心的子集及其 RAM 的一部分。如果核心访问来自同一节点内的内存,则称为本地访问。 同样,对不同节点的访问称为远程访问。远程访问比本地访问具有更长的延迟,因为它们必须遍历一个或多个互连链路,这是节点之间也为缓存一致性流量服务的通信路径。图 1 是一个典型的 NUMA 系统的示意图,该系统具有四个节点,每个节点有四个核心。在撰写本文时,NUMA 系统最多可构建八个节点,每个节点十个核心。
当前的 x86 NUMA 系统是缓存一致性的(称为 ccNUMA),这意味着程序可以透明地访问本地和远程节点上的内存,而无需更改代码或特殊的操作系统支持。这使得可以轻松迁移到 NUMA 系统,但它没有解决重要的性能考虑因素。一个幼稚的实现——例如,一个将其所有内存都分配在单个节点上的程序——很容易导致过多的远程访问或内存控制器的过载。
为了避免 NUMA 系统上的性能陷阱,需要考虑节点的连接方式、程序内存的放置位置以及程序如何访问该内存。以前的 NUMA 感知操作系统专注于局部性,试图不惜一切代价最大限度地减少远程访问的数量,以避免性能损失。然而,现代 NUMA 系统与旧系统相比,具有显着不同的延迟特性。远程访问大约比本地访问慢 30%,2,7 而在较旧的硬件上,远程访问可能慢七倍。3 在现代 NUMA 系统上,远程访问的惩罚已大大减少。
另一方面,当前的 CPU 会在内存子系统上产生巨大的负载,导致内存控制器和互连链路(如果请求是远程的)发生拥塞。如果多个核心大量访问单个节点,则由于拥塞,内存延迟可能长达 1,200 个周期 (!),而正常延迟仅约为 300 个周期。因此,避免内存控制器和互连拥塞成为现代 NUMA 系统上的关键问题。以下部分将研究拥塞对性能的影响。
基准测试可以提供 NUMA 系统性能特征的完整图景。此处选择 NAS(数值空气动力学模拟)、1 PARSEC(共享内存计算机的普林斯顿应用程序库)10 和 Metis MapReduce9 套件,因为它们的 CPU 利用率大于 30%,从而可以将重点放在 NUMA 效应上,而不是磁盘 I/O 或阻塞同步等其他因素。实验在 AMD 服务器上进行,该服务器具有四个四核 CPU,如下一节所述。
第一个实验量化了仅远程访问惩罚的效果,而没有内存子系统拥塞的存在。为此,基准测试仅使用单个线程运行,从而限制了内存控制器和互连上的压力,然后在两种不同的内存配置(本地和远程)下进行比较。在本地内存配置中,应用程序在其内存和线程位于同一节点上执行。在远程内存配置中,使用标准 Linux 工具强制应用程序线程在其内存的不同节点上运行。因此,在远程内存情况下,所有内存访问都是远程的,而在本地内存情况下,所有内存访问都是本地的。
图 2a 显示了在本实验中使用的应用程序的单线程版本在本地和远程内存配置之间的性能差异。即使所有内存请求都是远程的,性能降级也从未超过 20%。
尽管远程访问惩罚在可能的情况下值得最小化,但这并不是 NUMA 性能影响的全部内容。为了证明这一点,基准测试使用多个线程运行,每个核心一个线程,并在两种不同的常见 NUMA 内存分配策略下运行:首次访问和交错。Linux 的默认策略是首次访问,其中内存分配在与首次访问内存页面的线程相同的节点上。首次访问策略旨在最大限度地提高本地访问相对于远程访问的比例,但当然它不能保证本地访问,因为数据可以由多个节点上的线程共享。另一方面,交错策略在所有节点上均匀分配内存分配,而不管哪些线程访问它。交错确保内存分配是平衡的,但不一定内存访问是平衡的。这两种策略都在页面(通常为 4 KB)的粒度上工作。
图 2b 显示了多线程应用程序版本的首次访问 (F) 和交错 (I) 之间的绝对性能差异。应用程序根据哪种策略性能最佳进行标记 (F) 或 (I)。该图通过显示每个基准测试的最佳策略和最差策略之间的性能差异来比较这两种策略。如果差异可以忽略不计,则应用程序标记为 (-)。首先要注意的是,没有一种策略对所有应用程序都是最佳的。一些应用程序在使用首次访问策略时性能最佳,但许多应用程序更喜欢交错。第二个要注意的是,超出远程访问惩罚的 NUMA 效应确实会严重影响性能。对于 Streamcluster 基准测试,使用首次访问策略几乎使运行时间比交错策略增加了一倍。
我们通过使用硬件性能计数器收集以下关键指标,进一步研究了 Streamcluster 和 PCA(另一个在使用首次访问策略时性能损失显着的基准测试)的 NUMA 性能特征
• 本地访问率。 导致本地访问的 RAM 访问的比例。
• 内存延迟。 执行 RAM 访问所需的周期数,平均而言。更高的延迟意味着 CPU 必须在最后一级缓存未命中时停顿更长时间,这将对性能产生负面影响。
• 内存控制器不平衡。 内存控制器负载的标准偏差(占平均值的百分比),其中负载以每时间单位的请求数衡量。与互连不平衡一起,它是拥塞的标志。
• 平均互连使用率。 互连链路的平均带宽利用率。较低的互连使用率可能意味着应用程序的内存密集度不高,或者由于某些链路未充分利用而存在不平衡。
• 平均互连不平衡。 互连链路的带宽利用率的标准偏差(占平均值的百分比)。
• L3MPKI。 每 1,000 条指令的最后一级缓存未命中数。这是衡量应用程序对内存子系统施加多少压力以及应用程序对内存延迟的敏感程度的相对指标。
• IPC(每周期指令数)。 对于相同的应用程序和工作负载,更高的 IPC 意味着更好的性能。
表 1 报告了 Streamcluster 和 PCA 的指标。流量拥塞效应通过首次访问 (F) 和交错 (I) 策略下每个基准测试的关键 NUMA 指标的差异来突出显示。两种 NUMA 策略之间的性能差异不能用最后一级缓存未命中率的变化来解释,最后一级缓存未命中率保持不变。也不能用本地访问率来解释,本地访问率对于 Streamcluster 保持不变,实际上对于性能更好的交错策略的 PCA 来说更差。当交错内存时,PCA 的本地访问率从 33% 下降到 25%,但性能显着提高,因此结论是更好的局部性不一定能提高性能。
当使用首次访问策略时,这两个应用程序都显示出拥塞迹象,具有高最后一级缓存未命中率、内存控制器不平衡和互连不平衡。拥塞导致高内存延迟。在 Streamcluster 的情况下,首次访问策略的平均内存延迟是交错策略延迟的两倍以上。交错平衡了节点之间的内存,从而减少了流量热点和拥塞,因此提高了内存延迟和整体性能。图 3 显示了 Streamcluster 的内存流量和拥塞的可视化;顶部显示了首次访问下的流量不平衡,底部显示了交错。承载大部分流量的节点和链路在尺寸上按比例放大,颜色也更鲜艳。百分比值显示了定向到每个节点的内存请求的比例。
图 2 和表 1 中的结果激发了一种 NUMA 内存管理算法,该算法重视拥塞管理,而不是仅仅关注减少远程访问。这并不是说减少远程访问不重要(毕竟,它们确实会增加延迟并导致互连拥塞),但这不应该是唯一的目标。有效管理拥塞意味着关注内存访问流量如何在系统中分布。仅仅使用交错是不够的。许多应用程序不会受到不平衡的影响,因此它们会不必要地产生远程访问延迟(例如,图 2b 中更喜欢首次访问策略的基准测试)。该算法必须能够根据应用程序的访问模式智能地放置内存,以便在可能的情况下减少拥塞,但在拥塞最小时不会牺牲局部性。由于访问模式是先验未知的,因此该算法还必须能够确定访问模式,并在运行时以低开销移动内存。
在后面的部分中,我们将介绍我们的 NUMA 算法,称为 Carrefour,它考虑了所有这些因素。但是,首先,接下来的两节将介绍 Linux 上可用的现有 NUMA 工具。(本文概述了 Carrefour 算法。有关完整讨论,包括实现细节和详尽的实验结果,请参阅 Dashti 等人6。)
Linux 允许管理员通过 numactl 实用程序为应用程序设置 NUMA 策略。可用的 NUMA 策略包括首次访问、交错以及将分配限制为特定节点。如前所述,首次访问是将在与首次访问内存页面的 CPU 相同的节点上分配内存的策略,而交错策略以循环方式在节点上分配内存页面。
Linux 通过 libnuma 库和相关的系统调用向程序员公开手动 NUMA 内存管理功能。这允许程序查询 NUMA 拓扑,为特定地址范围设置 NUMA 策略,并在运行时将内存页面迁移到不同的节点。(有关 Linux NUMA 功能的详细信息,请参阅 Lameter8。)
Linux 还为硬件性能计数器提供了强大的支持,硬件性能计数器用于计数 CPU 事件,例如经过的周期数、退役的指令数、分支预测错误或缓存未命中。这些事件可用于计算前面列出的重要 NUMA 指标。Perf 是使用硬件性能计数器分析应用程序的标准 Linux 工具。它可以收集多个事件的数据,性能开销可忽略不计,并且开发人员的工作量也很少。
硬件指令采样是一种类似于性能计数器的高级 CPU 功能。通过指令采样,一部分指令由硬件标记。标记的指令将记录有关其执行的额外信息。它对于获取一些与 NUMA 相关的统计信息是必要的,包括内存访问延迟和内存访问的地址。该功能在 AMD CPU 上实现为 IBS(基于指令的采样),在 Intel CPU 上实现为 PEBS(精确的基于事件的采样)。不幸的是,Linux 对硬件指令采样的支持有限,并且大多数用途都需要自定义内核模块。
AutoNUMA4 旨在为 Linux 提供更主动的 NUMA 解决方案。内核任务定期迭代每个进程的已分配内存,并统计该进程在每个节点上的内存页面数。它还会清除页面上的存在位,这将强制 CPU 停止并在下次访问页面时进入页面错误处理程序。
在页面错误处理程序中,它会记录哪个节点和线程正在尝试访问页面,然后再设置存在位并允许执行继续。从远程节点访问的页面被放入队列中,以便迁移到该节点。但是,在页面已经迁移一次之后,未来的迁移需要来自远程节点的两次记录访问,这旨在防止过度迁移(称为页面抖动)。
AutoNUMA 的内存放置算法,现在称为自动 NUMA 平衡,已合并到 Linux 内核中。可以通过 sysctl 接口通过将 kernel.numa_balancing
设置为 1
来启用它。
AutoNUMA 还使用线程放置来尝试提高局部性。如果迁移或交换线程会导致更多线程访问成为本地访问(基于收集的页面错误统计信息),但不会以在 CPU 之间引入负载不平衡为代价,则调度程序将考虑迁移或交换线程。
Carrefour 是一种用于 NUMA 系统的内存放置算法,它专注于流量管理:放置内存以最大限度地减少互连链路或内存控制器上的拥塞。
Carrefour 使用全局信息和内存使用统计信息来告知限制拥塞的三种主要技术
• 内存并置。 将内存移动到不同的节点,以便访问很可能成为本地访问。
• 复制。 将内存复制到多个节点,以便来自每个节点的线程可以在本地访问它(对于只读和以读取为主的数据很有用)。
• 交错。 移动内存,使其均匀分布在所有节点之间。
所有这三种技术都在之前的研究中单独分析过,但 Carrefour 将它们组合成一种新颖的算法,该算法对于现代 NUMA 系统非常有效。
为了结合这些技术并明智地应用它们,Carrefour 从硬件性能计数器收集每个页面、每个进程和全局统计信息。Carrefour 还使用硬件指令采样来记录哪些线程和节点访问哪些内存页面。与 AutoNUMA 的页面错误处理程序技术相比,指令采样让 Carrefour 能够以低开销收集更多样本,因为它每个样本的开销更低。
Carrefour 使用的第一个指标是每微秒的 RAM 访问次数。如果它小于阈值(在我们的实验中为 50),则算法的其余部分将完全禁用,直到它变得大于阈值。如果 RAM 访问率较低,则应用程序不太可能从更好的内存放置中受益,因此此规则可防止在不需要 Carrefour 时产生开销。如果算法确实保持启用状态,则 Carrefour 会迭代它已收集统计信息的内存页面,并应用复制、并置和交错技术。
我们在 Linux 内核中通过虚拟内存层的补丁实现了内存复制,并且我们的实现能够在写入复制页面时自动维护一致性。要启用复制,必须有足够的可用内存,并且至少 95% 的应用程序内存访问必须是读取,因为写入复制页面的性能成本非常高。复制特定页面的规则很简单:如果观察到页面有来自多个节点的只读模式访问,则复制这些页面。复制提高了局部性和拥塞,因为可以从多个节点本地访问复制的页面。
如果本地访问率低于 80%,则启用并置。仅由单个远程节点访问过的页面将迁移到该节点,从而提高局部性。
交错的主要目的是通过在多个节点之间分配内存(以及内存访问)来缓解拥塞。第一步是考虑内存控制器不平衡。如果它低于 35%,则认为交错无利可图,并且全局禁用它。否则,已记录来自多个节点的读取和写入访问的页面将迁移到随机节点,其中迁移到特定节点的概率与该节点内存控制器的相对负载成反比。
Carrefour 的源代码可在 https://github.com/Carrefour 获取。
所有实验均在 AMD 系统上进行,该系统具有 64 GB RAM 和四个四核 Opteron 8385 处理器,运行频率为 2.3 GHz。它分为四个 NUMA 节点,每个节点具有四个核心和 16 GB RAM(拓扑结构如图 1 所示),通过 HyperTransport 1.0 链路互连。
操作系统为 Linux kernel v3.6,AutoNUMA 配置使用了 v27 补丁。
各种多线程基准测试用于评估:PARSEC 基准测试套件 v2.1、10 FaceRec v5.0、5 Metis MapReduce 基准测试套件9 和 NAS 并行基准测试套件 v3.3。1 PARSEC 基准测试使用“原生”工作负载,NAS 基准测试使用问题大小,这些问题大小提供至少 10 秒的运行时间。CPU 利用率低于 33% 的应用程序被排除在外,因为它们不受内存管理策略的影响。每个配置和基准测试运行 10 次,这导致 Carrefour、默认 Linux 和交错配置的标准偏差小于 2%。AutoNUMA 给出的标准偏差高达 9%。
我们评估了 Carrefour 相对于 Linux 默认策略(首次访问)、手动交错内存使用 Linux 交错策略和 AutoNUMA 补丁的性能改进。图 4 和图 5 显示了相对于默认 Linux 的性能改进。
应用程序通常分为三类。第一类是那些无论使用哪种 NUMA 技术都具有相同性能的应用程序(例如,Bodytrack 和 Swaptions)。这些应用程序不是内存密集型的,并且往往具有较低的最后一级缓存未命中率。它们也不会因 Carrefour 或 AutoNUMA 而产生太多开销,因为大部分开销与应用程序的内存密集程度成正比。
第二类应用程序是内存密集型的,但默认的首次访问策略对它们效果很好。BT、CG、DC、FT、MG 和 UA 属于这一类。对于这些应用程序,手动交错会损害性能,因为它消除了首次访问的局部性优势,而没有减少拥塞。另一方面,Carrefour 不会导致不良的内存放置,而只有很小的开销。
其余基准测试在默认 Linux 下受到不良内存放置的影响。AutoNUMA 能够提高其中一些应用程序的性能,但对于其他应用程序(例如,FaceRec 和 PCA),它只有很小的影响。另一方面,Carrefour 显着提高了这些应用程序的性能,并且在两种情况下,Carrefour 大大优于第二好的技术。它将 FaceRecLong 的性能提高了 120%,而手动交错仅将性能提高了 60%。同样,Carrefour 将 Streamcluster 的性能提高了 180%,而手动交错仅将其提高了 100%。
一个例外是 IS,手动交错可以改进 IS,但 Carrefour 不能。Carrefour 的采样和迁移率无法跟上 IS 产生的流量突发,因此内存没有及时平衡以提高性能。
我们进一步分析了选定的应用程序,以查看 Carrefour 如何影响关键的不平衡、局部性和延迟指标。图 6 和图 7 显示了结果。图 6 显示了选定基准测试的负载不平衡。越低越好。
在图 6a 中,Carrefour 始终最大限度地减少内存控制器的不平衡,手动交错也是如此。AutoNUMA 有时能够减少不平衡,但通常程度不如 Carrefour,并且在 FaceRec 的情况下,它使不平衡比默认 Linux 更糟。图 6b 中描述的互连链路上的不平衡显示了类似的趋势。
尽管手动交错能够减少不平衡,但它始终以牺牲局部性为代价。这在图 7a 中显而易见。另一方面,Carrefour 始终具有最高或接近最高的本地内存访问率。对于在默认 Linux 下具有良好局部性的应用程序(MG 和 SP),AutoNUMA 保留了良好的局部性,但能够提高 Facesim 的局部性。
不平衡和本地访问率的影响反映在内存访问延迟中,如图 7b 所示。正如预期的那样,Carrefour 为每个分析的应用程序产生了最低的(或并列最低的)平均内存延迟。平均内存延迟与基准测试的性能之间也存在很强的相关性。例如,Streamcluster 和 FaceRec 在 Carrefour 下内存延迟大幅降低,并且它们在图 4 中显示出巨大的性能提升。
总的来说,我们可以得出结论,Carrefour 系统地解决了几乎所有情况下的 NUMA 内存放置问题,在某些情况下能够大大优于其他技术,并且不会显着损害任何应用程序的性能。
NUMA 架构用于扩展当今服务器级系统的处理器数量。在不久的将来,预计系统将具有更多的 NUMA 节点和更复杂的 NUMA 拓扑结构。此处描述的实验表明,NUMA 的性能影响是显着的,并且该问题并非微不足道,这促使我们进行认真的研究和全面的解决方案。
与之前的 NUMA 研究相反,我们的实验发现拥塞导致了最严重的 NUMA 问题。当内存控制器的请求速率或互连上的流量速率过高时,就会发生拥塞,这会导致内存访问的过度延迟。可以通过平衡多个内存控制器和互连链路之间的流量来缓解拥塞。NUMA 性能的另一个因素是局部性,这是以前的 NUMA 算法所关注的重点。良好的局部性意味着大多数内存访问将是本地节点的,因此不会支付遍历互连链路的延迟成本。
如前所述,拥塞和局部性这两个 NUMA 问题很难调和,对于任何特定的应用程序,我们都无法预先知道最佳的内存放置。Carrefour 使用硬件性能计数器和硬件采样来在线确定应用程序的内存访问模式,且开销较低。然后,它利用这些知识应用三种页面级技术:内存复制、内存交错和内存并置。每种技术都有特定的用途:并置提高局部性,交错减少不平衡,复制在读取远远多于写入的情况下同时实现两者。Carrefour 的创新之处在于结合了这些策略,并且仅在适当的时候应用每种策略。
结果是,与默认 Linux 相比,Carrefour 能够提高许多应用程序的性能。对于两个基准测试 Streamcluster 和 FaceRecLong,使用 Carrefour 可以使性能提高一倍以上。与手动交错和 AutoNUMA 不同,Carrefour 永远不会因不正确的页面放置而显着降低性能。
随着 NUMA 系统的增长以及发出内存请求的核心数量的增加,NUMA 效应将继续成为一个令人关注的问题。Carrefour 展示了一系列有效减少这些担忧的技术。开发人员可以使用从 Carrefour 获得的 方法和见解,以及前面描述的工具,来优化其 NUMA 系统应用程序。
我们感谢 Oracle Labs 和不列颠哥伦比亚省创新委员会为这项工作提供的资金。
1. Bailey, D., et al. 1994. NAS Parallel Benchmarks. RNR Technical Report; http://www.nas.nasa.gov/publications/npb.html.
2. Boyd-Wickizer, S., Chen, H., Chen, R., Mao, Y., Kaashoek, F., Morris, R., Pesterev, A., Stein, L., Wu, M., Dai, Y., Zhang, Y., Zhang, Z. 2008. Corey: an operating system for many cores. In 8th Usenix Symposium on Operating Systems and Design: 43-57.
3. Brecht, T. 1993. On the importance of parallel application placement in NUMA multiprocessors. In Proceedings of the Usenix Symposium on Experiences with Distributed and Multiprocessor Systems 4: 1.
4. Corbet, J. 2012. AutoNUMA: the other approach to NUMA scheduling. LWN.net; http://lwn.net/Articles/488709/.
5. CSU Face Identification Evaluation System. 2010. Evaluation of Face Recognition Algorithms. Colorado State University; http://www.cs.colostate.edu/evalfacerec/index10.php.
6. Dashti, M., Fedorova, A., Funston, J., Gaud, F., Lachaize, R., Lepers, B., Quema, V., Roth, M. 2013. Traffic management: a holistic approach to memory placement on NUMA systems. In Proceedings of the 18th International Conference on Architectural Support for Programming Languages and Operating Systems; 381-394.
7. David, T., Guerraoui, R., Trigonakis, V. 2013. 关于同步,你想知道的一切,但又不敢问。《操作系统原理第二十四届 研讨会论文集》: 33-48。
8. Lameter, C. 2013. 非均匀内存访问概述。《 通讯》,56(9): 59-65。
9. Metis MapReduce 库;http://pdos.csail.mit.edu/metis/。
10. PARSEC 基准测试套件;http://parsec.cs.princeton.edu/.
Fabien Gaud 是 Coho Data 的高级软件工程师,专注于性能和可扩展性。他于 2010 年在格勒诺布尔大学获得博士学位,并于 2011 年至 2014 年在西蒙弗雷泽大学担任博士后研究员。
Baptiste Lepers 是西蒙弗雷泽大学的博士后研究员。他的研究课题包括性能分析、NUMA 系统的优化和多核编程。他喜欢在山区度过周末,进行徒步旅行和自行车运动。
Mohammad Dashti 和 Justin Funston 是西蒙弗雷泽大学的博士生。Mohammad 拥有 SFU 的计算机科学硕士学位和伦敦国王学院的移动通信硕士学位。他的研究重点是操作系统、GPGPU 和异构 CPU/GPU 系统,而 Justin 的研究兴趣包括内存管理、线程调度和多核系统。
Alexandra Fedorova 于 2006 年在哈佛大学在 Margo Seltzer 的指导下获得博士学位。2006 年至 2015 年,她曾任 SFU 计算机科学学院的助理教授,后升任副教授。Alexandra 于 2015 年加入不列颠哥伦比亚大学 ECE 系。她的研究重点是计算机系统的性能、可用性和能源效率。
Vivien Quéma 是法国格勒诺布尔 INP (ENSIMAG) 的教授。他的研究是关于理解、设计和构建(分布式)系统。他的研究方向包括拜占庭容错、多核系统和 P2P 系统。
Renaud Lachaize 是法国格勒诺布尔大学的助理教授。他的研究兴趣领域是操作系统和分布式系统,目前特别关注多核系统。
Mark Roth 就读于西蒙弗雷泽大学,并于 2007 年获得学士学位,2012 年获得硕士学位。他目前在 Google 担任工程师。
最初发表于 Queue vol. 13, no. 8—
在 数字图书馆 中评论本文
Adam Morrison - 多核程序中的可扩展同步
为现代多核处理器设计软件提出了一个难题。传统的软件设计,其中线程操作共享数据,具有有限的可扩展性,因为对共享数据更新的同步会串行化线程并限制并行性。 替代的分布式软件设计,其中线程不共享可变数据,消除了同步并提供了更好的可扩展性。 但是,分布式设计使得实现共享数据结构自然提供的功能(例如,动态负载平衡和强一致性保证)具有挑战性,并且根本不适合每个程序。 然而,通常,共享可变数据结构的性能受到当今使用的同步方法的限制,无论是基于锁的还是无锁的。
Spencer Rathbun - 使用 Promise 进行并行处理
在当今世界,有很多理由编写并发软件。 提高性能和增加吞吐量的愿望导致了许多不同的异步技术。 然而,所涉及的技术通常很复杂,并且是许多细微错误的根源,特别是当它们需要共享可变状态时。 如果不需要共享状态,那么这些问题可以通过称为 Promise 的更好抽象来解决。 这些允许程序员将异步函数调用连接在一起,等待每个函数返回成功或失败,然后再在链中运行下一个适当的函数。
Davidlohr Bueso - 实用同步原语的可扩展性技术
在理想世界中,应用程序有望在越来越大的系统上执行时自动扩展。 然而,在实践中,不仅不会发生这种扩展,而且在更大的系统上看到性能实际上变得更差是很常见的。
John T. Richards, Jonathan Brezin, Calvin B. Swart, Christine A. Halverson - 并行编程的生产力:十年的进步
2002 年,DARPA(国防高级研究计划局)启动了一项 HPCS(高生产率计算系统)的重大计划。 该计划的动机是相信,即将到来的并行机器的利用受到以 peta 规模编写、调试、调整和维护软件的难度的限制。