我原本以为MESI等缓存一致性协议可以提供伪原子性but仅跨个人内存加载/存储指示。如果我执行获取、修改、写入指令组合,仅使用 MESI 将无法在第一条指令到最后一条指令之间强制执行原子性。
然而,英特尔参考手册第 3a 卷第 8 节说:
8.1.4 LOCK 操作对内部处理器缓存的影响
对于 P6 和更新的处理器系列,如果内存区域
在 LOCK 操作期间被锁定的信息被缓存在处理器中
正在执行 LOCK 操作作为回写存储器并且是
完全包含在高速缓存行中,处理器可能不会断言
总线上的 LOCK# 信号。相反,它会修改内存位置
内部并允许其缓存一致性机制来确保
操作以原子方式执行。这个操作称为“缓存
锁定。”缓存一致性机制自动防止两个或
更多处理器缓存了相同的内存区域
同时修改该区域的数据。
http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf
这似乎与我的理解相矛盾,暗示不需要使用 LOCK 指令,因为可以使用缓存一致性?
锁定作为一个概念与实际的总线 #lock 信号之间存在差异 - 后者是实现第一个锁定的方法之一。缓存锁定是另一种更简单、更高效的方法。
MESI 协议保证,如果一条线路由某个核心(无论是否修改)独占,则没有其他人拥有它。在这种情况下,您可以通过在缓存中添加简单的标志来自动执行多个操作,该标志会阻止外部窥探,直到操作完成。这将具有与锁概念所规定的相同的效果,因为没有其他人可以改变甚至观察中间值。
在更复杂的情况下,该行不是由单个高速缓存保存(例如,它可能在多个高速缓存之间共享,或者访问可能会在两个高速缓存行之间分割,并且只有一个高速缓存在您的高速缓存中 - 场景列表通常是实现具体且可能没有由 CPU 制造商披露) - 在这种情况下,您可能不得不求助于“较重”的大炮,例如总线锁,这通常可以保证no one can do anything在共享巴士上。显然,这对性能有巨大影响,因此可能仅在您别无选择时才使用。在大多数情况下,一个简单的缓存级锁就足够了。请注意,像 Intel TSX 这样的新方案似乎以类似的方式工作,当您在缓存中工作时提供优化。
顺便说一句 - 您关于单个指令的伪原子性的假设也是错误的 - 如果您提到单个内存操作(加载或存储),那么它是正确的,因为一条指令可能包含多个指令(inc [addr]
例如没有锁就不是原子的)。您的引用中也出现的另一个限制是访问需要包含在缓存行中 - 即使在单个加载或存储中,分割行也不能保证原子性(因为它们通常实现为稍后合并的 2 个内存操作) )。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)