我试图了解 CPU 管道的“获取”阶段如何与内存交互。
假设我有这些说明:
4: bb 01 00 00 00 mov $1,%ebx
9: bb 02 00 00 00 mov $2,%ebx
e: b3 03 mov $3,%bl
如果 CPU1在 CPU2 执行这些相同的指令时写入00 48 c7 c3 04 00 00 00
内存地址 8(即 64 位对齐)会发生什么情况?指令流会自动从 2 条指令变为 1 条指令,如下所示:
4: bb 01 00 00 00 mov $1,%ebx
9: 48 c7 c3 04 00 00 00 mov $4,%rbx
由于 CPU1 正在写入 CPU2 正在读取的同一内存,因此存在争用。写入会导致 CPU2 管道在刷新其 L1 缓存时停止吗?假设 CPU2 刚刚完成了对 的“获取”pĥase mov $2
,是否会为了重新获取更新的内存而将其丢弃?
此外,将 2 条指令更改为 1 条指令时存在原子性问题。
我发现这个很老的文档 提到“指令获取单元在每个时钟周期从指令高速缓存中获取一个 32 字节的高速缓存行”,我认为这可以解释为每条指令从L1,即使它们共享相同的缓存行。但我不知道这是否/如何适用于现代 CPU。
如果以上是正确的,这意味着在获取mov $2
到管道之后,下一次获取可能会在地址处获取更新的值e
并尝试执行00 00
( add %al,(%rax)
),这可能会失败。
但是,如果 fetchmov $2
带入mov $3
“指令缓存”,那么认为下一次 fetch 只会从该缓存中获取指令(并 return mov $3
)而不重新查询 L1 是否有意义?只要它们共享一个高速缓存行,这将有效地使这两条指令的获取原子化。
那么它是哪一个?基本上有太多的未知数,我只能推测太多,所以我真的很感激管道的 2 个获取阶段如何与它们访问的内存交互(变化)的逐个时钟周期细分。