Intel Core & Enhanced Core微架构(6)

版权声明:转载必须保留原出处,没有书面许可不可用于商用目的, https://blog.csdn.net/qq_43401808/article/details/85705898

Instruction PreDecode

指令预译码器从指令Cache或者指令预取缓存区中接收16字节的指令流,执行如下的预译码操作:

  • 确定每条指令的长度(注:x86指令是变长指令)
  • 译码每条指令的指令前缀
  • 为译码器标记每条指令的不同属性(例如,“是分支指令”)

指令预译码器可以每个周期想指令队列写入6条x86指令。如果读取的指令行含有超过6条指令,预译码器每个周期译码6条指令,直到指令行中所有的指令都译码完毕。然后才开始译码下一个指令行。

例如,如果一个指令行含有7条指令,预译码器在第一个周期会译码前6条指令,然后在第二个周期译码1条指令。平均下来,每个周期译码3.5条指令。尽管看起来每周期指令数(IPC)指标没有完全优化(即没有达到理想的每周期6条指令),但是实际上这个速度已经高出大部分程序的性能了。通常情况下,软件无需为了避免指令饥饿而采取额外的优化措施。

在指令长度译码阶段,下面的指令前缀可能会导致性能问题。这些前缀可以动态的改变指令的长度,被称为指令长度切换前缀(LCP):

  • 操作数长度覆盖前缀(66H), 当指令使用单字长立即数时,这个前缀位于指令前

例如指令MOV ax, 1234H对应的十六机制机器码是66 B8 34 12(66即是操作数长度覆盖前缀)

  • 地址长度覆盖前缀(67H),在实模式,16位或32位保护模式下,当指令使用ModR/M字节时。

例如,指令MOV eax, [si]对应的十六进制机器码是"67 8B 04"(67即使地址长度覆盖前缀)

当预译码器在指令行中碰到LCP前缀时,它必须使用一个慢速的指令长度译码算法。使用这个算法,预译码器需要6个周期才能完成指令行译码,而不是通常的1个周期完成。而且通常的处理器流水线中的排队机制也无法隐藏/覆盖LCP前缀导致的额外周期数。

注意,在Intel 64位架构指令集中的REX前缀(4xH)可以改变两类指令的长度:MOV指令的位移量和MOV指令的立即数。但是这个前缀并不会导致LCP损失,因此它不被认为是LCP前缀。(todo:补充一个例子)

Instruction Queue

指令队列是18指令深度,即有18个条目,可以保存18条指令,位于指令预译码器指令译码器之间。它每个周期可以发送最多达5条指令,同时支持1个宏熔合操作。指令队列也可以作为小于18条指令的循环的高速缓存(简称为循环缓存)使用,具体操作后面有讲解。

BPU中有一个循环流侦测器(LSD)。这个LSD可以尝试侦测循环指令,符合条件的循环结构的指令会被锁定在指令队列中,至此循环指令可以由指令队列提供,直到分支预测失败导致循环结束。当循环指令在指令队列中“回放”时,即指令队列(向执行核)提供循环指令,可以获得更高的指令带宽以及更低的功耗(因为流水线前端中的其他部件可以关闭,例如取指单元,预译码器等)。

LSD提供了如下的优势:

  • 对于采纳分支没有带宽损失
  • 对于未对齐的指令没有带宽损失
  • 没有LCP损失,因为预译码阶段已经完成
  • 降低前端的能耗,因为指令Cache,BPU以及预译码器可以空闲

软件应该“机会主义式地”使用循环缓存功能。循环展开以及其他的优化方法可能导致循环长度太大,以至于无法符合LSD条件。对于追求高性能的代码,循环展开通常是更被推荐的优化方法,尽管这种方法可能导致LSD不可用。

Instruction Decode

Intel Core微架构有4个指令译码器,第一个,译码器0,可以译码最多4微指令的Intel 64与IA32指令,即译码器0将x86指令译码后对应的微指令条数不超过4条。另外3个译码器可以译码单微指令的x86指令,即一条x86指令译码后对应一条微指令。微指令序列生成器可以每周期生成3条微指令,辅助译码超过4微指令的x86指令。

注:Intel Architecture Optimization (Order#: 245127-001)的附录C中介绍了Pentium II & III处理器上常用指令对应的微指令条数。大部分x86指令都对应单条微指令,例如AAA,CLC,CMC,DAS等,复杂的指令,例如AAM,RET等,对应4条微指令。更复杂的指令,例如RSM,STI等,则需要微指令序列生成器辅助译码。需要注意的是,同一条指令的不同格式,可能会生成不同条数的微指令,例如ADD指令,ADD AL, imm8对应单条微指令,ADD r8, m8对应2条微指令(大约是读操作数,然后做加法),ADD m8, imm8则对应4条微指令(大约是读操作数,做加法,再写回内存)。Intel并未公布微指令的细节,以及单条x86指令对应的详细微指令序列。

所有的译码器都支持单微指令流的常见情况,包括:微熔合,栈指针跟踪,和宏熔合。因此,即使那3个简单译码器也不仅限于译码单微指令的x86指令。将指令按照4-1-1-1的模式排列既无必要也不再推荐。

宏熔合将两条x86指令合并成单条微指令。在32位操作模式下(包括Intel 64位模式下的兼容模式),Intel Core微架构可以每周期进行一次宏熔合;但是在64位模式下不做宏熔合,因为使用长指令(指令字节数)的代码通常很难利用到宏熔合机制。

注:处理器的Intel 64位模式实际包括两种子模式:兼容(子)模式和64位(子)模式。兼容模式使得64位操作系统可以运行传统的32位软件;64位模式使得64位操作系统可以运行访问64位线性地址空间的64位应用程序。

猜你喜欢

转载自blog.csdn.net/qq_43401808/article/details/85705898