首页 文章

什么时候CPU可以忽略LOCK前缀并使用缓存一致性?

提问于
浏览
5

我原本以为缓存一致性协议(如MESI)只能在各个 memory-load/store 指令中提供伪原子性 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

这似乎与我的理解相矛盾,暗示LOCK指令不需要使用,因为可以使用缓存一致性?

2 回答

  • 3

    锁定作为概念与实际总线#lock信号之间存在差异 - 后者是实现第一个的手段之一 . 缓存锁定是另一个更简单,更高效的锁定 .

    MESI协议保证如果某一行仅由某个核心(无论是否经过修改)持有,则没有其他人拥有它 . 在这种情况下,您可以通过在缓存中添加简单标志来原子地执行多个操作,该标志会阻止外部监听,直到操作完成 . 这与锁定概念所指示的效果相同,因为没有其他人可以改变甚至观察中间值 .

    在更复杂的情况下,线路不是由单个缓存保存(例如,它可以在多个缓存之间共享,或者访问可以在两个缓存线之间分开,并且只有一个在缓存中 - 场景列表通常是实现具体而且可能没有被CPU制造商披露) - 在这种情况下,你可能不得不求助于像总线锁这样的大炮,这通常可以保证没有人可以在共享总线上做任何事情 . 显然这会对性能产生巨大影响,因此这可能仅在您没有其他选择时使用 . 在大多数情况下,简单的缓存级锁定就足够了 . 请注意,像英特尔TSX这样的新方案似乎以类似的方式工作,当您在缓存中工作时提供优化 .

    顺便说一句 - 你对单个指令的伪原子性的假设也是错误的 - 如果你提到单个存储器操作(加载或存储),那将是正确的,因为一个指令可能包含多个指令( inc [addr] ,例如,不会是原子的)没有锁) . 您的引用中还出现的另一个限制是访问需要包含在缓存行中 - 拆分行通常实现为2个稍后合并的内存操作 .

  • 1

    阅读你给出的摘录,我发现使用LOCK-ed指令并不矛盾 . 例如,考虑 INC 指令 . 如果没有 LOCK ,它可以读取原始值,其缓存行处于 SHARED 状态,这不会阻止同一缓存中的其他核心在存储相同的递增结果=数据竞争之前并发读取相同的值 .

    我解释了引用,因为每个缓存行粒度保证了数据完整性,当数据适合一个缓存行时,可能不需要额外的注意 . 但是,如果数据跨越两个缓存行的边界,则必须断言对它们的修改将以原子方式处理 .

相关问题