微指令编码和微指令格式

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

1个回答

实际上我们用高级语言编写的程序,被编译成可执行程序,存放可执行程序的文件实际就是一些机器码,可以被硬件执行。在这一步,我们称其为机器指令(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  

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐