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

时间:2017-10-29 04:58:19

标签: c++ cpu barrier

我知道CPU可以重新排序

之类的指令
load A
load B

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

some_array[array_index] = new_value;
++array_index;

我猜它会从不,因为第二行依赖于第一行。我是对的吗?

1 个答案:

答案 0 :(得分:6)

不,你错了。

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

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

甚至:

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

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

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

这是你出错的地方:

  

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

只有当CPU和编译器都无法找出依赖关系并解开它时。但这在这里显而易见。通过计算出依赖关系,它们可以按任意顺序执行,编译器和CPU实际上确实可以找出这些类型的依赖关系(除此之外甚至更复杂),因为如果我们的软件 更慢,那么他们没有。

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

相关问题