Chris/King 2017-11-30 07:51 采纳率: 100%
浏览 5484

微指令编码和微指令格式

微指令的格式与微指令的编码息息相关,但是垂直型微指令它的编码方式是什么呢?我不太看得出来

  • 写回答

1条回答 默认 最新

  • jyl_sh 2018-01-03 03:54
    关注

    实际上我们用高级语言编写的程序,被编译成可执行程序,存放可执行程序的文件实际就是一些机器码,可以被硬件执行。在这一步,我们称其为机器指令(Machine Instruction),而到了这一步,往往也就以为自己到达了所谓的“底层”。

    前一段时间,我还在论坛提过一个疑问,就是Intel编译器编译出的代码是针对Intel处理器优化的,在AMD处理器上执行效率一般,为什么会出现这个情况?因为机器指令序列都是一样的,每个机器指令按照硬件厂商给的参数,周期数(clock cycle)应该也差别不大啊。

    现在我想,我可以尝试来解答这个问题了。在我们看来,每一步机器指令都是一个原子操作,但是硬件为了追求更高的吞吐率(through output),将这些指令又细分成一个个独立的阶段,称之为微指令(micro-operation,μ-op),这些微指令可以在一个流水线(pipeline)的不同阶段中顺序执行执行,当流水线头部空了,就可以执行下一个机器指令的微指令。这样“同时”执行的机器指令就很多,从而增加了吞吐率。

    当然一味增加流水线的阶段也是不行的,因为从一个阶段到另一阶段有时间延迟(latency),并且这些阶段公用时钟信号,所以要用执行时间最长的阶段所需时间作为公共时钟,并且很多操作无法切割成太多的微指令。下图是奔4处理器的流水线示意图:

    所以,我之前的概念,mov reg reg这样的操作只需要耗费1个clock,这是错误的,正确的说法是这个操作的均摊时间是1个clock,它必须走完流水线所有的步骤,而流水线的每个步骤至少是1个clock的。一条机器指令的执行,包括取值、译码、计算、访存、更新PC等很多步骤,而微指令可以看成是译码以后的结果,它还可以缓存在buffer上,从而下次遇到相同的指令,减少译码时间。

    还有一个问题就是相邻的机器指令之间如果有依赖,上一个指令还没在流水线出来,下一个就进去了,这样下一个可能用了错误的值,这个问题可以用转发(bypass)上个流水线的中间值给下个流水线,或暂停(stall)来解决,但是stall是不合理的,因为这样使得流水线的一部分处于停滞状态,而还有一个方法,就是乱序执行(out of order),将后面没有依赖关系的指令提到前面来,尽量使流水线填充满。

    所以,可以想象,Intel和AMD的微指令层面,流水线肯定是非常不一样的。那么如何安排机器指令顺序(当然执行时CPU会判断能否乱序,但是这时已经是后期,如果编译器能更多的去除依赖当然就更好了),以及如何利用寄存器(有时同样的功能也可以用不同的机器码来实现)等等。所以Intel的编译器能够针对自家的CPU给出更高效的编译结果。

    例如:AMD文档给编译器开发者的一条建议是,当跳转后面紧跟ret指令时,最好插入一个rep,从而在不引入错误的前提下,提高CPU效率。

    [plain] view plain copy

    ......  
    je  .L33  
    rep  
    ret  

    评论

报告相同问题?

悬赏问题

  • ¥15 Matlab问题解答有两个问题
  • ¥50 Oracle Kubernetes服务器集群主节点无法访问,工作节点可以访问
  • ¥15 LCD12864中文显示
  • ¥15 在使用CH341SER.EXE时不小心把所有驱动文件删除了怎么解决
  • ¥15 gsoap生成onvif框架
  • ¥15 有关sql server business intellige安装,包括SSDT、SSMS。
  • ¥15 stm32的can接口不能收发数据
  • ¥15 目标检测算法移植到arm开发板
  • ¥15 利用JD51设计温度报警系统
  • ¥15 快手联盟怎么快速的跑出建立模型