首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器完成的指令重排序与cpu完成的指令重新排序之间的关系是什么?

编译器完成的指令重排序与cpu完成的指令重新排序之间的关系是什么?
EN

Stack Overflow用户
提问于 2019-01-17 21:10:03
回答 1查看 925关注 0票数 3

好的,所以出于性能原因,编译器可以自由地重新排序代码片段。让我们假设一些代码片段,直接翻译成机器代码,没有应用优化,如下所示:

代码语言:javascript
复制
machine_instruction_1
machine_instruction_2
machine_instruction_3
machine_instruction_4
machine_instruction_5

但是,智能编译器决定原始顺序效率很低,并重新排序相同的代码,因此产生的机器指令的新顺序如下:

代码语言:javascript
复制
machine_instruction_5
machine_instruction_4
machine_instruction_3
machine_instruction_2
machine_instruction_1

到目前一切尚好。

这里是棘手的部分开始。得到的机器指令将由cpu执行,只要保持代码逻辑,cpu就可以自由地对它们进行重新洗牌。由于我们正在处理两个“层”的指令重新排序:

  • 第一个原因是编译器的优化。
  • 第二种,由于cpu的无序执行。

是什么使编译时指令重新排序相关呢?cpu所看到的只是一系列原始机器指令,没有显示编译器先前执行的任何优化。如果cpu引入了自己的“层”重排序,它为什么不使编译器设置的指令顺序失效呢?基本上,是什么迫使cpu尊重编译器优化?编译时重新排序和运行时重新排序如何“合作”,后者如何补充前者?

EN

回答 1

Stack Overflow用户

发布于 2019-01-17 22:36:35

在考虑指令执行时,必须尊重的是程序的语义。任何命令都是正确的,只要这一点得到尊重。具体而言,这是由“依赖项”描述的,该“依赖关系”指示某些指令是否需要程序正确行为的给定顺序。例如,考虑以下程序

代码语言:javascript
复制
1 x <= y+3
2 z <= 2*x
3 w = 5*y
4 y = 2*a

指令1和2是依赖的。如果他们的相对排序被修改,程序就不符合程序员的要求,任何重新排序都是被禁止的。由于不同的原因,在y被1和3使用之前,4不能不变地执行。有不同的依赖关系,包括在考虑控制流时。

编译器和硬件试图重新排序程序,以提高其效率,同时尊重依赖性。事实上,它们的行动是相辅相成的。

编译器可以考虑比处理器更大的重组,并使用更复杂的启发式方法来实现。编译器可以对程序有一个大的视图,并重新排序大部分代码。理论上,如果不存在依赖关系冲突,并且编译器认为它可以改进程序的执行,则可以在1000的距离上替换一个指令。它可以完全重组代码,展开循环等。相反,处理器有一个相对有限的预取指令窗口,可以考虑重新排序,而任何重新排列只能涉及封闭指令,并且基于一个周期内可行的简单方法。

但是处理器有很大的优势。它可以对随机事件进行动态重新排序和响应。在给定的时间,它考虑可以执行哪些指令与依赖项和数据可用性有关,并相应地重新排序代码。这是基于动态依赖关系的,例如,如果由于缓存丢失而无法获得前一个依赖项指令的结果,它将执行其他尊重依赖项的指令。同一程序在相同输入数据下连续运行会导致不同的排序,这取决于分支错误预测、缓存丢失等。

因此,编译器和处理器之间没有竞争,而是高效的协作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54244337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档