从1996 到2003:微处理器的基本形态
经过了十多年的讨论,微处理器的体系结构沉淀了许多优秀的设计思想,诞生了许多教科书级的微处理器值得我们深入研究。
MIPS R10000
R10000 作为MIPS 架构中较成熟的微处理器,是教科书中的常客。从整体的设计上看,R10000[31] 几乎所有的优化措施都是围绕如何隐藏内存延迟展开的。
执行部件在更大的指令范围和更宽的发射宽度上工作,尽可能保持指令流平稳。MIPS R1000 采用5 级流水,可以同时获取和发射4 条指令,拥有5 个执行单元,定点、浮点和地址队列各能容纳16 条指令。
指令发射之前进行寄存器重命名工作,尽可能解除虚假的指令相关。使用24 个比较器并行检测译码的4 条指令之间的相关性,比较器的个数是n2 量级的。延迟槽技术对于早期的MIPS 处理器来说是一种性能优势,但是在超标量指令集中并没有什么性能优势,保留这种性质只是为了兼容性的要求。
Cache 采用两级结构,并且以非阻塞的方式访问,尽可能隐藏Refill 延迟。L1 Cache 在片内,使用虚拟地址索引,数据和指令Cache 各有32KB 大小,占据了全部晶体管数量的三分之一。L2 Cache 在片外。R10000 没有实现原子指令,而是通过LL/SC 来替代原子指令。
通信方面使用64 位分离事务系统总线,可以连接至多4 个R10000 微处理器,同时处理8 个读请求。利用这些特性可以将多个R10000 组成ccNUMA 服务器,例如SGI Origin[47]。
MIPS R10000 还提供了大量的硬件性能计数器用于性能分析工作,相比于软件层面的分析技术,硬件计数器能够为架构师提供更为详细的性能数据。文献[48] 给出了R10000 的性能计数器列表,并举例说明如何使用性能计数器开展性能分析工作,例如Cache Miss 的次数、预取的效率、分支误预测的代价以及访存延迟的分布。性能计数器并不仅仅对硬件工程师有所帮助,软件工程师同样可以利用性能数据修改代码逻辑,从而获得更好的Cache 性能和分支预测正确率。
DEC Alpha 21264
1998 年的Alpha 21264[36, 49] 是一款设计出色的微处理器,使用了很多先进的技术,其中的设计经验后来被其他微处理器设计者所吸收。但出色的设计并没能从商业上挽救这家公司,最终被Compaq 收购。
Alpha 21264 使用经典的联合分支预测器[34],同时使用Line 和Way 的预测,预测失败时代价为1 个空泡。
乱序执行方面,继续使用自家的计分板技术。定点发射队列有20 项,分成两组发射共计4 条指令,这样既保证了较多的发射数量,又简化了硬件设计。两组之间通过一个额外的周期进行通信,性能分析的结果表明这样做的影响可以忽略。浮点发射队列有15 项,每周期可发射两条指令。
访存方面,Cache 的周期比CPU 要短一倍,这样就能在一个周期访问两次。和R10000 一样,Alpha 21264 也采用了L1 Cache 在片内,L2 Cache 在片外的方案。Load/Store 操作可以被乱序执行,但如果发生了错误,那么会给相关的指令设置一个等待位,被设置了等待位的访存操作不会被乱序执行。除此之外,Alpha 21264 提供了Cache 预取的指令,可以让程序员根据实际程序的需求制定Cache 预取策略。
为了组成多路的小型服务器,21264 支持标准的MOESI 的Cache 一致性协议,并提供外部接口支持多处理器互连。
Intel Pentium 4
2000 年Intel 推出了重新设计的Pentium 4 微处理器,但是这时候设计的目标并非进一步提升性能,而是尽可能的提高主频,响应市场对主频的追求。Pentium 4 的微架构代号为NetBurst,流水级被划分为20级,尽可能的减少每一级流水线的功能。整数核心设计频率高达9GHz[50],但实际上在4GHz 左右就一头撞到了功耗墙上,性能上甚至不如前代Pentium III。尽管如此,我们仍然来看一下Pentium 4 的架构[51]。
首先,较高的时钟频率迫使处理器每一级的逻辑变得简单,因此复杂的阶段可能使用多个周期。更快的主频和更深的流水级带来更多的性能提升,分支误预测的性能损失也更大,总的来说还是会带来性能的提升。不过20 级左右的流水线深度差不多已经是极限了,很少能看到更多的设计。
L1 I Cache 被称为Execution Trace Cache,存储译码好的uop,这里体现了RISC 的设计理念。Trace Cache 每一行可以打包六条指令,一共包含12K 条微指令。前端具有自己的分支预测器(Trace BTB),有4K个分支目标项;没有分支历史的项使用静态预测的方法:看他是向前还是向后。同时L1 I Cache也有自己的页表,并且提供页级别的保护。而译码器每个周期其实只能译码一条指令,Intel 自己也知道指令集太复杂了。较为复杂的指令使用Microcode ROM 查表,每次可以查出来多条指令。
在乱序执行方面,P4 使用多个独立的调度器,尽管只有4 个发射端口,但定点部件半周期可以发射一条指令,因此最大可达到6 发射。保留站每周期可以退出至多3 条指令。
Pentium 4 最初使用180nm 的工艺,后来使用了90nm 的工艺,并且增加了新的功能[52],主要体现在Hyper-Threading 超线程技术和SSE3 指令集的扩展上。
IBM Power 4
IBM 的Power 系列长期以来服务于商业领域,逐渐形成了自己的技术特色。每一代Power 产品都会在的内部期刊IBM Journal 上发表非常详细的架构设计文章,每次都看的我头疼[46, 53–56]。2002 年的Power4[32] 同样如此。
Power4 的设计理念有6 条,分别是;1.SMP 优化;2. 全系统设计;3. 高主频;4.reliability, availability, and serviceability(RAS);5. 平衡技术和商业性能;6. 二进制兼容性。这些设计理念对我们今天仍有指导意义,不仅是这六条理念价值,更重要的是提出这六条规则的心态和能力更值得我们学习。
和桌面级的产品不同,IBM 的财大气粗和面向服务器的设计需求使得它的微处理器可以有更大的设计空间。首先,POWER4 是第一个商用的多核(双核)处理器。其次,同时期的产品还停留在L2 Cache 的时候,IBM 已经用上了L3 Cache,并且通过复杂的打包技术支持至多32 路互连。
由于IBM 使用自己的指令集,因此可以在指令中添加许多指示位帮助微处理器做性能上的优化,例如指示跳转指令可能的跳转方向。通过为分支指令、比较指令提供专门的执行单元,Power4 具有多达8 个执行单元,浮点单元的功能也更强,可以执行乘加指令,提高指令效率。
为了提供足够的操作数,相应的Load/Store Unit(LSU) 所占的芯片面积也相当大,并且提供硬件的数据预取机制。IBM 通过前端将复杂指令译码为精简指令,再通过group 技术将多条指令打包成group 一起发射,物理资源分配和指令提交也是这样。和x86 类似,有些复杂的指令可以被译码成许多条精简指令,这些精简指令自成一组,从而保证指令的原子性。但是,当中断发生时,group 的指令就需要被拆解开一条一条的处理,从而完成精确中断。
Power4 使用复杂而细致的Cache 状态维护一致性,并且尽可能利用紧邻的内存提供数据,系统的一致性维护在L2 Cache 中进行。在系统互连方面,IBM 的外部接口并非使用固定的频率,而是和CPU 的频率保持一定的比例,以此获取系统的灵活性。
由于IBM 的客户中有很多是金融机构,系统的可靠性就显得尤其重要,因此IBM 同年发表的Micro 上的文章[57] 重点描述Power4 在高可靠性上所做的努力。在hardware 和firmware 的协同努力下,Power4可以支持故障屏蔽、内部冗余、错误恢复和全系统的动态可配置等方面,显著延长系统的平均故障时间。系统的可靠性将是设计服务器芯片时的重要标准。
AMD Opteron
终于写到AMD 的了,在开始之前先说一句,“AMD, yes!”
首先说Opteron 的微处理器架构[35]。AMD Opteron 微处理器支持x86 的64 位扩展,同时兼容32 位指令。在SIMD 指令的支持方面,支持SSE 和SSE2 指令,对应的寄存器数量增加到16 个,性能分析的结果表明16 个向量寄存器可以满足程序80% 的需求。乱序执行方面,Opteron 有6 个发射端口,浮点和定点各3 个,定点运算和地址生成可以共用地址单元定点流水线为12 级,浮点为17 级,两类指令使用分离的重命名单元。
取指部件在取值的同时识别指令的边界,并将指令写入指令Cache。每周期可译码3 条x86 指令,和Intel 跟IBM 类似,AMD 同样使用简单译码器、复杂译码器和查表获取指令三者相结合的方式提供稳定的指令流。在访存的处理上,L1 和L2 Cache 之间为互斥关系,使用伪LRU 替换算法可以减少一半的bit 位。Store 必须顺序提交,而Load 指令则可以越过前面的指令。为了提升性能,Opteron 同样使用了数据预取机制。ECC 技术已经作为微处理器设计的基本技术,这里使用DRAM 的空闲周期完成错误矫正。
历史上内存控制器位于北桥,而将北桥集成到CPU 内部使得Opteron 获得了20% 相对于Athlon 的性能提升,和北桥相关的资料在文献[58] 中有进一步的描述。没有了北桥,Opteron 设计使用Hyper-Transport技术互连,以适应服务市场对2 到8 路服务器的需求。Opteron 使用交叉开关连通5 个端口,system request interface (SRI)、内存控制器和3 个HT 接口。请求逻辑上被划分为四类:Request、Posted request、Probe和Response,使用四个虚拟的通道。互连技术并不保证处理器请求的顺序,因此微处理器需要自己保持请求之间的顺序。性能分析的结果表明,互连微处理器的性能与拓扑参数,平均半径,之间存在强相关。为了增加系统的直连能力,16 位宽的HT 接口可以分成两条8 位宽的HT 接口使用,这样可以有效降低远程内存访问的代价。尽管文中有对一致性协议的相关描述,但我们选择通过另一篇文献来详细描述这方面的实现。
有关12 核Opteron 架构的代号”MAGNY COURS” 的微处理器内存子系统的文献[59] 发表时已经到了2010 年了,严格来说不在标题的范围之内,但还是放在这里介绍。新一代的Opteron 芯片上有6 个微处理器核,每个核心有512KB 的私有L2 Cache,通过SRI 连接到6MB 的L3 Cache 上,L3 Cache 里开辟了一小块空间存放目录数据。通过打包技术,可以在每个package 上集成两个芯片,这样每个模块就有了12 个微处理器核,从而提高数据中心的计算密度。HT 接口继承此前的设计,可以将数据链路分开使用,降低拓扑半径。Opteron 使用改进的MOESI 协议标记Cache 状态,使用基于广播的目录协议维护Cache 一致性,并通过有限指针和Probe Filter 进一步过滤广播信息,降低带宽压力。这样设计是多年设计经验、量化研究和理论创新的综合成果。