原子操作(任何比较和交换或原子加/减)的成本是多少?消耗多少周期?它会暂停 SMP 或 NUMA 上的其他处理器,还是会阻止内存访问?
它会刷新乱序 CPU 中的重新排序缓冲区吗?
对缓存会有什么影响?
我对现代流行的 CPU 感兴趣:x86、x86_64、PowerPC、SPARC、Itanium。
这几天我查了一些实际数据,但一无所获。
不过,我做了一些研究,将原子操作的成本与缓存未命中的成本进行了比较。
x86 LOCK 前缀的成本(包括lock cmpxchg
对于原子CAS),在PentiumPro之前(如文档中所述),是内存访问(如高速缓存未命中),+停止其他处理器的内存操作,+与试图锁定总线的其他处理器的任何争用。然而,从 PentiumPro 开始,对于正常的 Writeback 可缓存内存(应用程序处理的所有内存,除非直接与硬件对话),不是阻止所有内存操作,而是仅阻止相关的缓存行(基于中的链接)@osgx 的回答).
即,核心延迟响应该线路的 MESI 共享和 RFO 请求,直到存储实际的部分之后。lock
编辑操作。这称为“高速缓存锁”,并且仅影响该高速缓存行。其他核心可以同时加载/存储甚至CASing其他线。
实际上,CAS 情况可能更复杂,如上所解释的这一页,没有时间限制,但由值得信赖的工程师进行了富有洞察力的描述。 (至少对于在实际 CAS 之前执行纯加载的正常用例来说是这样。)
在讨论太多细节之前,我会说锁定操作的成本是一次缓存未命中+与同一缓存行上的其他处理器可能发生的争用,而CAS+前面的加载(几乎总是需要的,除了互斥锁,在互斥锁上你总是需要这样做) CAS 0 和 1) 可能会导致两次高速缓存未命中。
他解释说,单个位置上的加载 + CAS 实际上可能会导致两次缓存未命中,例如加载链接/条件存储(请参阅此处了解后者)。他的解释依赖于知识MESI缓存一致性协议。它对缓存行使用 4 种状态:已修改 (Modified)、独占 (Exclusive)、共享 (Shared)、I(nvalid)(因此称为 MESI),下面将根据需要进行解释。场景解释如下:
- LOAD 导致缓存未命中 - 相关缓存行在共享状态下从内存加载(即仍然允许其他处理器将该缓存行保留在内存中;在此状态下不允许进行任何更改)。如果该位置在内存中,则跳过此高速缓存未命中。可能的成本:1 次缓存未命中。(如果缓存行处于共享、独占或修改状态,即数据位于该 CPU 的 L1 缓存中,则跳过)。
- 程序计算要存储的新值,
- and it runs an atomic CAS instruction.
- 它必须避免并发修改,因此必须从其他CPU的缓存中删除缓存行的副本,以将缓存行移动到独占状态。可能的成本:1 次缓存未命中。如果它已经是独占的,即处于独占或修改状态,则不需要这样做。在这两种状态下,没有其他 CPU 持有高速缓存行,但在独占状态下,它尚未被修改。
- 在这次通信之后,变量在我们的 CPU 的本地缓存中被修改,此时它对所有其他 CPU 都是全局可见的(因为它们的缓存与我们的缓存是一致的)。最终会按照通常的算法写入主存。
- 尝试读取或修改该变量的其他处理器首先必须以共享或独占模式获取该缓存行,并且这样做将联系该处理器并接收缓存行的更新版本。
相反,锁定操作只会导致缓存未命中(因为将在独占状态下直接请求缓存行)。
在所有情况下,缓存行请求都可能被其他已经修改数据的处理器所阻止。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)