|

- UID
- 107645
- 帖子
- 596
- i贡献值
- 4 点
- We用劵
- 0 张
- 注册时间
- 2006-3-15
- 最后登录
- 2010-3-12
|
4#
发表于 2008-4-8 16:41
| 只看该作者
2、解码
当X86指令进入指令队列后,它们就等着被解码成微操作指令(uop),这是一种类似于RISC的指令。Core 2和Nehalem都有4个解码器,一个复杂解码器和3个简单解码器。简单解码器能够处理可以解码成一个uop的X86指令,现在绝大多数SSE指令都是这种。复杂解码器能够处理解码成1-4个uop的X86指令,而比这还要复杂的指令,则由微代码序列器(microcode sequencer)来处理。
Nehalem改进了宏操作融合(macro-op fusion)。Core 2可以在32bit模式下,把TEST/CMP(比较指令)和其后的Jcc(条件分支指令)给解码融合成一个微操作(uop):CMP+Jcc。这样就增加了解码带宽,并减少了微操作数量。而Nehalem的宏操作融合则包括了更多的条件分支指令:JL/JNGE, JGE/JNL, JLE/JNG, JG/JNLE。TEST/CMP和这些条件分支指令都将被解码成一个微操作:CMP+ Jcc。而且,Nehalem的宏操作融合可以是32bit和64bit模式。这是很重要的,因为现在大多数服务器都运行的是64bit操作系统,即使是桌面电脑也开始更多的欢迎64bit操作系统了。
一旦X86指令解码成微操作,就进入有28个项目数的微操作缓冲(uop buffer),Nehalem将其作为前面介绍到的LSD(Loop Stream Detector,循环流检测器)。如果一个循环不大于28个微操作,则Nehalem就可以将其缓存在LSD里,并发送到乱序执行引擎去执行,而关闭指令拾取单元和解码器。这样通过关闭解码器和使用更大的循环,就能够比Core 2的LSD节省更多的能耗。Nehalem的28项的微操作缓冲,能够保存相当于21-23条X86指令(根据在一些游戏中的测试情况得出的估计)。X86指令转换为微操作的比率取决于工作量的不同,不过总的来说,Nehalem具有比Core 2更大一些的LSD缓冲。
比较有趣的是,Nehalem的LSD缓冲看起来更象是指令追踪缓存(trace cache)。指令追踪缓存的目标是以动态程序的顺序来存储微操作,而不是象指令缓存里那样以静态编译顺序存储X86指令,因此可以从关键路径(critical path,指需要时间最长的路径)中去掉解码器和分支预测器,而使得被堵塞的地方可以立刻取得指令。P4的指令追踪缓存的问题在于它太脆弱了,当其命中失败时,就必须一个接一个地(重新)解码指令。通常指令缓存的命中率是在90%以上,而指令追踪缓存却远低于这个标准,很少时候超过80%,大多数时候是在50-60%。也就是说,在40-50%的时间里,P4都表现得象是一个单发射微处理器,而不能够完全利用上它的执行资源。而Nehalem的LSD缓冲取得了和指令追踪缓存几乎同样的目标,而且当它无法工作的时候(即当循环太大时),也没有什么要命的性能损失。
在LSD缓冲之后,解码步骤的最后一步是专用堆栈引擎(dedicated stack engine),除去所有被堆栈更改过的微操作。堆栈更改过的微操作都是被一个专用加法器给执行过了的,并写到前端的一个推测寄存器(speculative delta register)。推测寄存器偶尔会和重命名结构的寄存器(renamed architectural register)同步,而重命名结构寄存器中则保存有堆栈中的非推测值(non-speculative value)。当堆栈处理过的微操作都被清除之后,剩下的微操作就进入乱序执行引擎去被重命名、发送、分配和执行。 |
|