cpu 是否对相互依赖的指令重新排序?

does cpu reorder instructions that are dependent on each other?

我知道 CPU 可以重新排序指令,例如

load A
load B

但是 CPU 会重新排列以下代码吗? (换句话说,另一个核心上的第二个线程 运行 会以相反的顺序看到结果吗?)

some_array[array_index] = new_value;
++array_index;

我猜它 永远不会 因为第二行依赖于第一行。我说得对吗?

不,你错了。

编译器和 CPU 可以完全自由地优化和重新排序代码,只要结果对于保证的任何行为都是相同的。不能保证其他线程将看到任何特定顺序的修改。因此,例如,CPU 和编译器可以自由实现与此代码相同的代码:

++array_index;
some_array[array_index - 1] = new_value;

甚至:

tmp = array_index;
++array_index;
some_array[tmp] = new_value;

由于没有违反保证,编译器和 CPU 可以自由进行这些优化。这是一件好事,因为它们可以显着加快代码速度。

如果您需要更多保证,您可以使用适当的工具(锁、障碍、原子等)来获得它们。但是没有理由不关心这些东西的代码应该被拒绝这样的优化。

这是你出错的地方:

I'm guessing it will NEVER because the second line is dependent on the first line. Am I right?

仅当 CPU 和编译器都无法找出依赖关系并将其解开时。但这在这里很明显。弄清楚依赖关系后,它们可以按任意顺序执行,编译器和 CPU 实际上会弄清楚这些类型的依赖关系(甚至更复杂的依赖关系),因为我们的软件将是 如果他们不这样做, 会慢很多。

但即使依赖性是不可撤销的,也不需要以任何特定顺序使实际写入对其他线程可见。它们可以位于 CPU 的写入发布缓冲区中并以任何顺序执行。另一个线程也可能重新排序读取,CPU 进行预读。