我知道CPU可以重新排序指令
load A
load B
Run Code Online (Sandbox Code Playgroud)
但是CPU会重新排序以下代码吗?(换句话说,在另一个核心上运行的第二个线程会以相反的顺序看到结果吗?)
some_array[array_index] = new_value;
++array_index;
Run Code Online (Sandbox Code Playgroud)
我猜它永远不会因为第二行依赖于第一行.我对吗?
不,你错了.
编译器和CPU完全可以自由地优化和重新排序代码,只要结果对于任何保证的行为都是相同的.其他线程将无法保证以任何特定顺序进行修改.因此,例如,CPU和编译器可以自由地实现与此代码相同的代码:
++array_index;
some_array[array_index - 1] = new_value;
Run Code Online (Sandbox Code Playgroud)
甚至:
tmp = array_index;
++array_index;
some_array[tmp] = new_value;
Run Code Online (Sandbox Code Playgroud)
由于不会违反任何保证,编译器和CPU可以自由地进行这些优化.这是一件好事,因为它们可以使代码明显加快.
如果您需要更多保证,可以使用适当的工具(锁,障碍,原子等)来获取它们.但是没有理由不关心这些东西的代码应该被拒绝这样的优化.
这是你出错的地方:
我猜它永远不会因为第二行依赖于第一行.我对吗?
只有当CPU和编译器都无法找出依赖关系并解开它时.但这在这里显而易见.随着依赖想通了,他们可以以任何顺序进行,编译器和CPU其实弄清楚这些种类的依赖关系(甚至更复杂的问题之外)的这样做,因为我们的软件会是多少,如果他们没有慢.
但即使依赖关系是不可撤销的,也不要求实际的写入以任何特定顺序对其他线程可见.它们可以位于CPU的写入发布缓冲区中,并以任何顺序执行.另一个线程也可能重新排序读取,CPU正在进行预读.