gpt4 book ai didi

performance - 原子操作成本

转载 作者:行者123 更新时间:2023-12-03 05:14:37 25 4
gpt4 key购买 nike

原子操作(任何比较和交换或原子加/减)的成本是多少?消耗多少周期?它会暂停 SMP 或 NUMA 上的其他处理器,还是会阻止内存访问?它会刷新乱序 CPU 中的重新排序缓冲区吗?

会对缓存产生什么影响?

我对现代流行的 CPU 感兴趣:x86、x86_64、PowerPC、SPARC、Itanium。

最佳答案

过去几天我一直在寻找实际数据,但一无所获。不过,我做了一些研究,将原子操作的成本与缓存未命中的成本进行了比较。

在 PentiumPro 之前(如文档中所述),x86 LOCK 前缀的成本(包括原子 CAS 的锁定 cmpxchg)是内存访问(如缓存未命中),+停止其他处理器的内存操作,+ 与其他试图锁定总线的处理器的任何争用。然而,从 PentiumPro 开始,对于正常的 Writeback 可缓存内存(应用程序处理的所有内存,除非直接与硬件对话),不是阻止所有内存操作,而是仅阻止相关的缓存行(基于 @osgx's answer 中的链接) .

即核心延迟响应该线路的 MESI 共享和 RFO 请求,直到实际锁定操作的存储部分之后。这称为“高速缓存锁”,并且仅影响该高速缓存行。其他内核可以同时加载/存储甚至CASing其他行。

<小时/>

实际上,CAS 情况可能更复杂,如this page 中所述。 ,没有时间限制,但由值得信赖的工程师进行了富有洞察力的描述。 (至少对于在实际 CAS 之前执行纯加载的正常用例来说是这样。)

在讨论太多细节之前,我会说锁定操作的成本是一次缓存未命中+与同一缓存行上的其他处理器可能发生的争用,而CAS+前面的加载(除了互斥体之外,几乎总是需要的,你总是 CAS 0 和 1) 可能会导致两次缓存未命中。

他解释说,单个位置上的加载 + CAS 实际上可能会导致两次缓存未命中,例如加载链接/条件存储(请参阅此处了解后者)。他的解释依赖于 MESI cache coherence protocol 的知识。它对缓存行使用 4 种状态:M(已修改)、E(独占)、S(已修改)、I(无效)(因此称为 MESI),下面将在需要时进行解释。场景解释如下:

  • LOAD 导致缓存未命中 - 相关缓存行在共享状态下从内存加载(即仍然允许其他处理器将该缓存行保留在内存中;在此状态下不允许进行任何更改)。如果该位置在内存中,则跳过此高速缓存未命中。 可能的成本:1 次缓存未命中。(如果缓存行处于共享、独占或修改状态,即数据位于该 CPU 的 L1 缓存中,则跳过)。
  • 程序计算要存储的新值,
  • 并且它运行原子 CAS 指令。
    • 它必须避免并发修改,因此它必须从其他CPU的缓存中删除缓存行的副本,以将缓存行移动到独占状态。 可能的成本:1 次缓存未命中。如果它已经是独占拥有的,即处于独占或修改状态,则不需要这样做。在这两种状态下,没有其他 CPU 持有缓存行,但在独占状态下,它尚未被修改。
    • 在这次通信之后,变量在我们的 CPU 的本地缓存中被修改,此时它对所有其他 CPU 都是全局可见的(因为它们的缓存与我们的缓存一致)。最终会按照通常的算法写入主存。
    • 尝试读取或修改该变量的其他处理器首先必须以共享或独占模式获取该缓存行,并且这样做将联系该处理器并接收缓存行的更新版本。相反,锁定操作只会导致缓存未命中(因为缓存行将在独占状态下直接请求)。

在所有情况下,缓存行请求都可能被已经修改数据的其他处理器阻止。

关于performance - 原子操作成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2538070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com