You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86内存模型下存储转发语义及部分重叠读写规则问询

关于Intel架构内存模型中部分重叠读写操作的语义疑问

通过实验不难弄清当前CPU的语义,但我想了解的是架构内存模型提供了哪些语义保障?我阅读了Intel SDM卷3第8章,认为其表述模糊,是否有遗漏之处?

手册明确指出:

  • 程序顺序中写操作之后的不同地址读操作,可能被重排至写操作之前。
  • 程序顺序中写操作之后的相同地址读操作,会在写操作之后执行。

同时手册提到:

在多处理器系统中,内存顺序遵循因果性原则。

关于存储转发仅提及一句:

本节描述的处理器顺序模型与Pentium和Intel486处理器所用模型基本一致。Pentium 4、Intel Xeon和P6系列处理器的唯一增强是:当读操作与同一内存地址的写操作重叠时,支持存储缓冲区转发。

手册还有示例(§8.2.3.5),通常示例不具规范性,但暂时按字面理解,该示例基本将第二条规则修正为:

  • 若程序顺序中写操作之后的读操作指向同一地址,则读操作必须“晚于”写操作,即要么观测到该写操作,要么观测到其他核心对同一地址的后续写操作;但第一种情况下,读操作可能在写操作对其他处理器可见前执行。

但手册未提及读操作与之前写操作部分重叠的情况,语义如何?以下是两个具体问题:

问题一

初始状态执行mov word [r1], 0,之后:
核心1

mov     byte [_x], 0x01
mov     r1, word [_x]

核心2

mov             eax, 0x0000
mov             r2, 0x0100
lock cmpxchg    word [_x], r3

是否必然仅存在以下两种情况之一?

  1. 写操作先于CAS执行,CAS失败,读操作得到0x0001。
  2. 写操作晚于CAS执行,CAS成功,读操作得到0x0101。
    不存在第三种情况:
  3. 写操作晚于CAS执行,CAS成功,但读操作因在写操作对其他核心可见前执行,仍得到0x0001。

问题二

更简单的场景:核心2不在_x附近写操作(可在其他地址写),仅核心1执行:

mov     byte [_x], 0x01
mov     r1, word [_x]

该读操作是否必须等待写操作对其他核心可见后才能执行?

这两个问题本质相同:若读操作与存储队列中的写操作部分重叠,能否转发存储队列中的重叠部分,其余部分按常规读操作处理?还是必须等待写操作完成后再执行读操作?手册仅提及读操作“指向同一地址”的情况,但此场景下读操作既包含写操作的地址,也包含其他地址。

有人可能这样推理:

  • 字读操作理论上是两个原子执行的字节读操作。
  • 将读操作拆分为两个读操作,每个读操作可独立重排至写操作对其他核心可见前;一个与写操作不重叠,一个完全匹配。
  • 将两个字节读操作重排至写操作后,再合并为一个原子读操作。

但我认为这种推理不成立:不能将原子操作拆分,对各部分应用非原子推理后再合并为原子操作。而且若该推理成立,问题一的答案是否定的,这是否违反因果性?

我的观点:

  • 若问题一答案为否,则违反因果性,存在矛盾。
  • 若问题一答案为是、问题二答案为否,则读操作可部分从存储队列转发、部分从缓存读取,但只能推测性执行,若在存储转发完成前其他核心独占缓存行,需回退。
  • 若两个问题答案均为是,则读操作可部分从存储队列转发、部分从缓存读取,但仅当执行写操作的核心已独占对应缓存行,且推测在写操作完成前无其他核心申请时,才能推测性执行。

实际中,问题一为是与两个问题均为是的情况差异极小,且我所知的处理器均不支持向部分重叠的读操作转发存储。因此两个问题的答案应均为是,但手册未明确说明。

内容的提问来源于stack exchange,提问作者Moonchild

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:06:05