编辑和你学扣肉:处理器的微架构

互联网 | 编辑: 2006-07-18 14:00:00编译 返回原文

我们首先从一个处理器微架构的速成教程开始学习。为了理解处理器设计的目标和优劣,你首先需要了解处理器执行的指令,所以我们从处理器运行的软件开始。

处理器微架构入门

处理器微架构入门

       我们首先从一个处理器微架构的速成教程开始学习。为了理解处理器设计的目标和优劣,你首先需要了解处理器执行的指令,所以我们从处理器运行的软件开始。

   典型的 X86 程序的代码中大约有50%的指令是存储器访问指令,其中存储器读指令大约是存储器写指令的2倍。然后,大约15%到20%的指令是分支指令(if, then,else等)。剩余指令中,大部分是诸如“ADD”、“MUL”这样的较简单的计算指令。像“DIV”、“SQRT”这些较复杂的计算指令在所有指令中只占很少的一部分。所有这些指令都按照典型的流水线步骤执行:取指,解码,取操作数,执行,退出。

   首先,处理器会根据指令指针寄存器(instruction pointer register)指示的地址取回指令。这时,对处理器来说,指令仅仅是一些没有意义的0、1字符串。只有在被解码之后,指令对处理器来说才开始有意义。指令被解码后可以得到操作数地址和操作码,而操作数地址可以在下一步发挥作用:取操作数。你不会希望处理器对操作数的地址进行计算,而是对那些地址里面存放的内容进行计算——与 C 语言里面的指针的概念很相似。当操作数被取出来以后,ALU根据操作码的指示,就可以对操作数进行正确的计算了。计算结果一般将被写回处理器内部的寄存器堆中。有时候,计算结果也需要写回到缓存和内存中。这就是最后的步骤——退出。到此为止,你应该略微了解一条指令的整个执行过程了。

   今天,对处理器设计者来说,主要的挑战是处理器的存储器访问平均延迟。在一个由 Pentium 4 3.6GHz 和 DDR400 内存构成的系统中,处理器的速度是内存的速度(200MHz)的18倍。也就是说,访问内存的每一个周期,处理器会经过18个周期。而且,发送一个内存访问请求需要多个内存周期,回应一个内存访问也需要多个周期。因此,对于 Pentium 4 来说,花费200到300个处理器周期来等待内存访问的完成并不罕见。设计处理器缓存的目标就是避免内存访问的发生。但即使处理器缓存的缺失率仅为4%,也就是说,在处理器访问存储器的所有情况中只有4%的比例需要访问内存,这4%也将显著降低处理器的执行效率。

Core微架构

Conroe微架构采用共享二级缓存设计,即两个核心共享4MB的二级缓存。采用共享缓存的好处是非常明显的,除了缓存容量容量利用率较佳,也可以减少缓存数据一致性对缓存性能所造成的负面影响。此外,因共享L2缓存之故,两个核心的第一阶缓存可直接对传数据,毋需通过外部的FSB,进而改善性能。此外还有更为重要的一点,当其中一个核心空闲时,另一个核心可已使用全部4MB缓存,大大提高缓存的使用率,有效提高系统性能。

Conroe 微架构的存储子系统

Conroe 微架构的存储子系统

  在处理器频率已经达到3GHz甚至更高的时代,保证即将用到的指令和数据已经在缓存中准备好是处理器设计者最重要的工作之一。因为只有这样,才能保证随着处理器频率的提高性能也随之提高;否则的话,更高的处理器频率只会使处理器花费更多的时钟周期来等待数据。这种把数据提前装入缓存的技术被称为“数据预取技术”(Prefeching)。但是,之前的处理器采用的数据预取技术并不能保证每次都成功,总会有一些失败的情况。这会导致处理器性能降低,特别是在运行对带宽敏感的应用程序的时候。

Conroe 微架构所采用的数据预取技术毫无疑问是目前为止最先进的,要优于 Pentium 4 和 Athlon 64 所采用的技术。Conroe 微架构中的每个核心至少有3组预取单元,包括2组数据预取单元和1组指令预取单元。除此之外,共享式二级缓存还拥有2组预取单元。这样,在一个双核心的采用 Conroe 微架构的处理器中,共有8组预取单元。有一个问题是,多达8组的预取单元在进行预取工作时,很容易会妨碍到正在运行的程序的正常的 load 操作。为了避免这种情况的发生,Conroe 微架构采取了预取监测器的机制,该监测器总会给予正在运行的程序更高的优先级。这样,预取单元就决不会从正在运行的程序那里“偷”走很多带宽了。

Conroe 微架构的预取机制还有更多新特性。数据预取单元经常需要在缓存中进行标签查找。为了避免引起正在运行的程序进行的标签查找的更高的延迟,数据预取单元使用标签查找的 store 端口。如果你还记得,load 操作的发生频率是 store 操作的2倍之多,那么就容易理解这样的选择了——store 端口的使用频率仅为 load 端口的一半。并且,store 操作在大多数情况下并不是影响系统性能的关键,因为在数据开始写入后,处理器可以马上开始进行下面的工作,而不必等待写入操作完成。缓存/内存子系统会负责数据的整个写入到缓存、复制到主内存的过程。

Conroe 微架构的缓存系统也令人印象深刻。二级缓存容量高达4MB,并且是由两个核心共享的,访问延迟仅12到14个时钟周期。每个核心还拥有32KB的一级指令缓存和一级数据缓存,访问延迟仅仅3个时钟周期。从 NetBurst 微架构开始引入的追踪式缓存(Trace Cache)在 Conroe 微架构中消失了。NetBurst 微架构中的追踪式缓存的作用与常见的指令缓存相类似,是用来存放解码前的指令的,对 NetBurst 微架构的长流水线结构非常有用。而 Conroe 微架构回归相对较短的流水线之后,追踪式缓存也随之消失,因为 Intel 认为,传统的一级指令缓存对短流水线的 Conroe 微架构更加有用。

Conroe微架构的解码单元

Conroe微架构的解码单元

Conroe 微架构会对取出的指令进行预解码。预解码信息包括指令长度和解码边界。

Conroe 微架构装备了4组解码单元,这是X86处理器世界的第一次。这4组解码单元包括3组简单解码单元和1组复杂解码单元。实际上,这种把简单指令与复杂指令分而治之的做法,并非是 P6 微架构的专利。从全世界第一个流水线化的X86处理器——80486开始,为了加速简单指令的执行,这原则就已经开始主导所有高速X86处理器的微架构。就算是号称提供三组“完整解码单元”的 AMD K7、K8 处理器,实际上也有类似的限制。

  在介绍下面的内容之前,首先让我们解释一下什么是微指令(Micro-Op)。由于X86指令集的指令长度、格式与定址模式都相当复杂,为了简化数据通路(Data Path)的设计,从很久以前开始,X86处理器就采用了将X86指令解码成1个或多个长度相同、格式固定、类似RISC指令形式的微指令的设计方法,尤其是涉及存储器访问的 load 及 store 指令。所以,现在的X86处理器的执行单元真正执行的指令是解码后的微指令,而不是X86指令。

  所以,对X86处理器来说,解码单元的任务不仅仅是解码出操作码和操作数的地址,还要把长度从1字节到15字节不等的X86指令转化成容易调度和执行的固定长度的类似RISC指令的微指令(Micro-Op)。

  常见的普通X86指令可以由3组简单解码单元中的任何一组翻译成1条微指令。另外1组复杂解码单元负责解码一些复杂的、需要翻译成4条微指令的X86指令。还有一些更长、更复杂的X86指令,需要微码序列器配合复杂解码单元来翻译成微指令。这种简单解码单元与复杂解码单元相配合的解码方式被现代的X86处理器所普遍采用,包括 P6 微架构、K7 处理器、K8处理器和 Pentium 4 处理器。

Conroe 微架构中的解码单元还拥有更多新特性。首先是宏指令融合技术(Macro-Op Fusion)。该技术可以把2条相关的X86指令融合为1条微指令。例如,X86比较指令cmp可以与跳转指令jne融合。这类情况一般发生在程序中的if-then-else分支语句中。

宏指令融合技术

  宏指令融合技术带来的效果是非常明显的。在一个传统的X86程序中,每10条指令就有2条指令可以被融合。也就是说,宏指令融合技术的引入可以减少10%的指令数量。而当2条X86指令被融合的时候,4组解码单元在单周期内一共可以解码5条X86指令。被融合的指令在后面的操作中完全是一个整体,这带来几个优势:更大的解码带宽,更少的空间占用,和更低的调度负载。如果 Intel 宣称的“每10条指令可以融合1次”的说法属实,那么宏指令融合技术本身就将带来巨大的性能提升。

  另外一项技术即微指令融合技术,是从之前的 Pentium M 处理器继承而来的。介绍这项技术之前,我们先来了解一下相关的问题和早期的解决办法。有一小部分X86指令处理起来非常困难,但是同时又是十分典型和常见的X86指令。一般来说,存储器寻址的算术操作就属于这一类指令,例如,ADD [mem], EAX。这表示把寄存器EAX的内容与地址为mem的内存单元的内容相加,并把计算结果写回该内存单元。

  在早期的处理器设计中,包括采用 P6 微架构的Pentium Pro、Pentium II 和 Pentium III 处理器,如果遇到这种类型的指令,那么解码单元将把它解码成2条甚至3条微指令。记住,从 P6 微架构之后的现代X86处理器的设计思想是把X86指令解码成类似RISC指令的微指令,然后再把这些微指令送往越来越RISC化的后端,而后端以类似RISC处理器的处理方式进行调度、发射、执行和退出。

  对于类似ADD [mem], EAX这样的指令,你没有办法送往RISC化的执行单元,因为它违反了 RISC 架构的根本规则——RISC 架构的处理器会把所有的数据 load 到寄存器,然后针对寄存器进行操作、计算等。

  因此,ADD [mem], EAX这条指令会被解码成多条微指令,简单示意如下:
MOV EBX, [mem]:读取[mem]的内容到寄存器
ADD EBX, EAX:对2个寄存器作ALU操作
MOV [mem], EBX:保存计算结果到[mem]

  自从 Banias 处理器之后,上面的load操作和ALU操作就可以用一条微指令来完成了。Intel 把该技术称为微指令融合技术(Micro-Op Fusion)。这项技术不是一件容易的事情:在旧的设计中,把load操作与ALU操作一起进行会导致对应的那一级流水线延迟加大,从而降低处理器所能达到的最高频率。(在处理器设计中,可能达到的最高频率取决于最慢的那一级流水线的延迟时间,即所谓的木桶效应。)只有可以并行执行、设计优秀的电路才使得在引入微指令融合技术的同时不显著降低处理器的频率。

  在预解码的阶段,处理器会识别可以应用微指令融合技术的指令。在解码阶段,类似 ADD [mem], EAX 的复杂指令就可以生成比旧架构数量更少的微指令。与宏指令融合技术带来的效果类似,这可以带来更大的解码带宽,更少的空间占用,更低的调度负载和更高的效率。

  微指令融合技术的目的就在于减少微指令的数目。处理器内部执行单元的资源有限,如果可以减少微指令的数目,就代表实际执行的X86指令增加了,可以显著提升执行效能。而且,微指令的数目减少还有助于降低处理器功耗,可谓有益无害。

  微指令融合技术所支持的范围,包括了整数运算、浮点运算和SSE2指令集等各种扩展指令集。根据 Intel 的官方说法,通过微指令融合技术,整数运算大约可以提升5%的性能,浮点运算大约可以提升9%的性能。

Conroe 微架构前端的改进还包括分支预测单元。分支预测行为发生在取指单元部分。首先,它使用了很多人们已经熟知的预测单元,包括传统的 NetBurst 微架构上的分支目标缓冲区(Branch Target Buffer,简称BTB)、分支地址计算器(Branch Address Calculator,简称BAC)和返回地址栈(Return Address Stack,RAS)。然后,它还引入了2个新的预测单元——循环回路探测器(Loop Detector,简称LD)和间接分支预测器(Indirect Branch Predictor,简称IBP),其中循环回路探测器可以正确预测循环的结束,而间接分支预测器可以基于全局的历史信息做出预测。Conroe 微架构在分支预测方面不仅可以利用所有这些预测单元,还增加了新的特性:在之前的设计中,分支转移总是会浪费流水线的一个周期;Conroe 微架构在分支目标预测器和取指单元之间增加了一个队列,在大部分的情况下可以避免这一个周期的浪费。

  下一课:英特尔®宽位动态执行(Intel® Wide Dynamic Execution)

返回原文

本文导航

相关阅读

每日精选

点击查看更多

首页 手机 数码相机 笔记本 游戏 DIY硬件 硬件外设 办公中心 数字家电 平板电脑