首页 > 解决方案 > 为什么 LOCK 在 x86 上是一个完整的障碍?

问题描述

为什么LOCK前缀会在 x86 上造成完全障碍?(因此它会耗尽存储缓冲区并具有顺序一致性)

对于LOCK/read-modify-write 操作,不需要完整的屏障,并且对缓存行的独占访问似乎就足够了。这是设计选择还是有其他限制?

标签: x86cpu-architecturememory-barriers

解决方案


很久以前,在 Intel 80486 之前,Intel 处理器没有片上缓存或写缓冲区。因此,根据设计,所有写入都立即按顺序在全球范围内可见,您不必从任何地方耗尽存储。通过完全锁定整个地址空间的总线来执行锁定事务。

在 486 和 Pentium 处理器中,已在片上添加了写入缓冲区,并且某些型号还具有片上缓存。首先考虑没有片上缓存的模型。所有写操作都暂时保存在片上写缓冲区中,直到可用时将它们写到总线上或发生序列化事件。请记住,原子 RMW 事务用于获取对软件结构或硬件资源的独占访问权。因此,如果一个处理器执行一个锁定事务,它不应该发生处理器认为它获得了资源的所有权,但是另一个处理器也以某种方式最终也获得了所有权。如果锁定事务的写部分被缓冲在写缓冲区中,然后总线锁被放弃,没有什么可以阻止其他代理同时获得对资源的访问权。本质上,写入部分必须对所有其他代理可见,而做到这一点的方法是不缓冲它。但是 x86 内存模型要求所有写入按顺序全局可见(这些处理器上没有弱排序)。因此,为了使锁定事务的写入部分全局可观察,所有缓冲的写入也必须以相同的顺序全局可观察。

一些 486 型号和所有奔腾处理器都有片上缓存。但是在这些处理器上,不支持缓存锁。这就是为什么锁定的事务不能在这些处理器上缓存的原因,因为保证原子性的唯一方法是绕过缓存并锁定总线。获取总线锁后,根据目标内存区域的对齐方式和大小执行一次或多次写入。在释放总线锁之前,写缓冲区仍然必须被清空。

Pentium Pro 引入了一些重大变化,包括弱排序写入、写入组合缓冲区和缓存锁定。所谓的“写入缓冲区”通常在更现代的微架构上称为存储缓冲区。锁定的事务在这些处理器上使用缓存锁定,但是在将锁定的存储从存储缓冲区提交到缓存之前,无法释放缓存锁,这使得存储全局可观察,这必然需要使所有早期存储全局可观察。这些事件必须按此顺序发生。也就是说,我认为锁定事务不必序列化弱序写入,但英特尔已决定采用这种方式。也许是因为英特尔想要一个方便的指令,在没有专用存储栅栏的情况下耗尽 PPro 上的 WC 缓冲区。


推荐阅读