原子性边界的界定—是理解 memory model 的核心之一。
SC 要求 atomicity of memory accesses , 下面将 memory accesses 进行拆解, 以 更深刻理解 SC 对 atomicity 的要求。
步骤回顾:
❗注意:写入寄存器不是 memory model 的可见性关键,因此不是原子性边界的一部分。
步骤回顾:
❗所以你说的 store 的 perform 阶段是必须原子的 —— 是完全正确的。
我之前说:
“Load 的两个阶段(issue, completion)构成其原子性边界。”
→ ✅ 正确,但需要明确 “completion” 是指 从 cache 得到值,不是写入寄存器。
我之前说:
“Store 的边界是从 issue 到 perform(全局可见)。”
→ ✅ 正确,但更精确地讲是:从 store buffer flush 到 coherence 完成 是关键部分。
操作类型 | 开始点 | 结束点 |
---|---|---|
Load | 发起 cache read | 数据拿到为止 |
Store | 发起 cache write | 数据在所有核心可见为止 |
你问得非常到位。这关系到 Sequential Consistency (SC) 模型中的核心假设和设计目标。
你提到的两个约束其实是:
于是问题来了:
为什么只强调了 Write Atomicity,而没有强调 Read Atomicity?
读(load)操作不会对其他核心产生直接可观察的副作用,它只是读取某个内存位置的当前值,并不会改变共享状态。而写操作会改变共享状态,是全局可观察事件。
所以,SC 中只需要定义:写什么时候被"别人"看到;读自然是基于"可见的写"结果。
在 SC 中,读到的值必须是某个已经完成的写,也就是说:
如果一个 core 看到
x = 1
,那么在它看来x = 1
这个写已经 globally visible 了(write atomicity 确保的)。
读到这个值是"合法"的前提是这个值是来自某个已经发生且"所有人都同意的"写。这一点正是 write atomicity 保证的。
所以 SC 中不需要额外声明 “read atomicity”——读只是在一组可见写中选一个。
因此,“read atomicity”没有意义:它不是一个互斥事件,也不需要所有 core "看到"某个读行为——它只是个本地动作。
// P0
x = 1;
y = 1;
// P1
if (y == 1)
assert(x == 1);
SC 要求:
关键是:
类型 | 是否强调原子性 | 原因 |
---|---|---|
Write | ✅ 强调 | 写影响全局状态,需要保证对所有核心同时可见 |
Read | ❌ 不强调 | 读只是查询当前状态,不会影响其他核心,不存在多核心“看到”问题 |
所以:SC 模型中只需要定义 Write Atomicity,Read Atomicity 不是一个有意义的概念。
如果你在考虑更弱的 memory model(如 TSO, RCsc, ARM, RISC-V 等),那时读操作就可能变得“更复杂”,因为 load-store reordering 和缓存的本地视图都会造成读操作行为更微妙。在那种模型下,load 有时也需要 fence 或 acquire-semantics 来保证语义,但那是更进一步的问题了。你也可以继续问这方面的内容。