在 Arm CPU 上对 TSO 内存模型的支持 (2024)
Source: Hacker News
作者:Jonathan Corbet
2024年4月26日
介绍
在 CPU 级别,内存模型描述了处理器在重新排序内存操作方面拥有的自由度(以及其他内容)。如果低层代码没有考虑内存模型,往往会出现令人不快的意外。自然,不同的 CPU 提供不同的内存模型,这会使某些类型的并发软件的可移植性变得更加复杂。为简化使用,一些 Arm CPU 提供了模拟 x86 内存模型的能力,但将该特性引入内核的努力正遭遇阻力。
CPU 设计者会竭尽所能提升性能。就内存访问而言,“一切”可能包括缓存操作、乱序执行、将多个操作合并为一次等。这些优化对单个孤立运行的 CPU 没有影响,但它们可能导致内存操作以出乎意料的顺序对其他 CPU 可见。系统中其他位置的轻率软件可能会看到与阅读代码时预期不同顺序的内存操作;this article 描述了一个简单的出错场景,而 this series on lock‑less algorithms 则详细展示了可用于避免内存顺序相关问题的一些技术。
x86 Total Store Ordering (TSO)
x86 架构实现了一种称为 全局存储顺序(TSO)的模型,该模型保证写入(存储)会按照执行顺序被所有 CPU 看到。读取同样不会被重新排序,但读取与写入之间的相对顺序并不保证。针对 TSO 架构编写的代码在许多情况下可以省略本来需要使用的昂贵屏障指令,从而强制特定的操作顺序。
Arm 内存模型
相反,Arm 内存模型更弱,赋予 CPU 更大的自由度来重新排列操作。此设计的好处是实现更简单,并且在不需要顺序保证的情况下(大多数情况下)能够获得更好的性能。缺点是并发代码需要更仔细地编写才能正确,而为更严格的内存模型(如 TSO)编写的代码在 Arm CPU 上运行时可能会出现(潜在细微的)错误。
较弱的 Arm 模型很少会成为问题,但有一种情况会出现问题:模拟 x86 处理器。如果 x86 模拟器没有同时模拟 TSO 内存模型,那么并发代码很可能会失败。然而,模拟 TSO 需要插入内存屏障,并会带来显著的性能惩罚。一类并发的 x86 代码——游戏——如果能够在 Arm CPU 上运行将受益匪浅;奇怪的是,这些用户不喜欢在缺乏性能或正确性的情况下面对兽人的大军。
Arm 上的 TSO
一些 Arm CPU 厂商已经了解这个问题,正如 Hector Martin 在该补丁系列中所描述的那样,他们在处理器中实现了 TSO 内存模型。部分 NVIDIA 和 Fujitsu CPU 始终以 TSO 运行;Apple 的 CPU 则将其作为可在运行时启用的可选特性。Martin 的目的是让用户空间能够看到并控制这一能力。
该系列首先添加了几个新的 prctl() 操作:
- PR_GET_MEM_MODEL – 返回 CPU 当前实现的内存模型。返回值可以是
PR_SET_MEM_MODEL_DEFAULT或PR_SET_MEM_MODEL_TSO。 - PR_SET_MEM_MODEL – 尝试启用请求的内存模型。返回码指示是否成功;内核可能会选择比请求更严格的模型。
- 在始终使用 TSO 的 CPU 上,请求 TSO 显然会成功。
- 在 Apple CPU 上,请求 TSO 会设置相应的 CPU 位。
- 在不支持 TSO 的 CPU 上请求 TSO 将会失败。
Martin 指出,这段代码并非全新:“该系列已经在下游的 Asahi Linux 树中酝酿了一段时间,并已向数千名用户发布”。有趣的是,Zayd Qumsieh 在一天前就提交了类似的补丁集,但那个版本仅在 Apple CPU 上的虚拟机中实现了该特性。
然而,对于期待在 Apple CPU 上玩更快游戏的用户来说,这两个补丁集都未受到内核中 Arm 架构代码维护者的欢迎。
- Will Deacon 表示了他的“强烈反对”,他说此特性会导致用户空间代码的碎片化。开发者可能会在发现问题消失后直接打开 TSO 位,从而产生在其他 Arm CPU 上会失败(甚至以微妙方式失败)的代码。
- Catalin Marinas 表示他会阻止任何让这种实现定义特性可用的补丁。
Martin 回应称碎片化不太可能成为问题,并以部分处理器(包括 Apple 的)支持的不同页大小为例,说明这些不兼容可以得到处理。他补充说,到目前为止,还没有人尝试将 TSO 特性用于除模拟器之外的其他用途,因此在其他软件中被滥用的可能性不大。他认为将其排除在外并不会改善局面:
“这里有一个务实的论点:既然我们需要它,而且如果被拒绝它仍然会在下游继续发布,这对碎片化风险的影响并不大,对吧?绝大多数在 Mac 上使用 Linux 的用户很可能在可预见的未来继续使用下游内核,以便比上游更快地获得新特性和硬件支持。因此,不在上游接受它并不会真正改变……”
Source:
Landscape vis‑a‑vis being able to abuse this or not, it just makes our life harder by forcing us to carry more patches forever.
Deacon, though, [insisted](/ml/linux-kernel/20240419165826.GB4020@willie-the-truck/) that, once a feature like this is merged, it will find uses in other software “and we’ll be stuck supporting it”.
If this patch is not acceptable, it is time to think about alternatives.
* One is to, as Martin described, just keep it out‑of‑tree and ship it on the distributions that actually run on that hardware. A long history of addition by distributions can, at times, eventually ease a patch’s way past reluctant maintainers.
* Another might be to just enable TSO unconditionally on Apple CPUs, but that comes with an overall performance penalty — about **9 %**, according to Martin.
* A third possibility was [mentioned](/ml/linux-kernel/87zftoqn7u.wl-maz@kernel.org/) by Marc Zyngier, who suggested that virtual machines could be started with TSO enabled, making it available to applications running within while keeping the kernel out of the picture entirely.
这类讨论往往不会很快消失。多年来,Linux 脱颖而出的众多方式之一,就是它能够让用户充分利用硬件;拒绝支持有用的硬件特性与这一历史背道而驰。虽然对该特性可能被滥用的担忧也源自长期经验,但这正是开发社区需要再次借鉴其悠久历史的时刻——通过寻找一种能够以可维护方式提供所需功能的解决方案。
索引
发表评论