为什么 LOCK 是 x86 上的完整屏障?

A. *_* S. 6 x86 cpu-architecture memory-barriers

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

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

Had*_*ais 7

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

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

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

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