问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

X86 CPU内部处理器架构细节—Nehalem

创作时间:
2025-01-22 06:20:27
作者:
@小白创作中心

X86 CPU内部处理器架构细节—Nehalem

Nehalem是Intel在2008年推出的微处理器架构,作为Core架构的继任者,它在多核设计、总线带宽和64位计算方面进行了重大改进。本文将深入探讨Nehalem架构的内部细节,包括其设计背景、核心功能、前端指令拾取和解码、执行引擎的乱序执行机制,以及重要部件如ROB、RRF、MOB等的作用。

Nehalem内核设计背景

Core架构源自Banias Pentium M处理器,主要针对笔记本电脑设计,具有高效、低耗的特点。然而,其双核设计、过时的FSB总线以及对64位计算支持不足等问题,限制了其在高性能多处理器企业级市场的发展。为此,Intel对Core架构进行了重大改进,推出了Nehalem架构。


4核心Nehalem处理器架构

核心:功能区间划分

Nehalem是一款乱序执行的超标量x86处理器。超标量设计允许多个执行单元同时处理无依赖性的指令,以提升指令级并行性。乱序执行则通过动态调度,使无数据关联的指令并行执行,从而提高整体效率。

前端:指令拾取和解码

处理器执行指令前,需先从L1指令缓存(I-cache)中加载指令。Nehalem的指令拾取单元(IFU)通过访问ITLB(指令转换后备缓冲器)读取指令,并进行预解码和分支预测。预解码后的指令进入指令队列,再由解码器将其翻译为微操作(uop)。

指令拾取单元(IFU)

由ITLB、指令预取器、L1指令缓存和指令预解码器组成。IFU每个时钟周期从L1指令缓存中拾取16字节的指令到指令长度解码器。当缓存命中时,16字节的指令将传输给指令预解码器。

分支预测单元(BPU)

在分支指令结果确定前预取和处理后续指令,避免处理器在执行预测路径时发生停滞。

指令预解码器(ILD)

接收Intel64指令,确定指令长度、解码指令前缀,并为解码器标注指令类型。

指令队列

缓存预解码后的指令,并每个时钟周期传递5条指令给指令解码器。

Nehalem采用3个简单解码器加1个复杂解码器。简单解码器将一条x86指令翻译为一条uop,而复杂解码器则将一些特别的x86指令翻译为1~4条uops。在极少数情况下,某些指令需要通过额外的可编程微代码解码器(MS ROM)解码为更多uops。

指令解码单元(IDU)将预处理后的Intel64指令(macro-ops)解码为uop,并将其放入下游的指令解码队列(IDQ)。对于一组uop,IDU会进行一些优化措施,如循环流监测和微融合。

执行引擎:乱序执行

执行引擎从上游的IDQ中选择micro-ops,动态调度分配给下游的执行单元执行。执行引擎是“out-of-order”的动态调度,超标量流水线允许micro-ops在代码语义不冲突的情况下并行的使用可用的执行单元。

执行引擎组件:

  • 寄存器重命名与分配单元(RRAU):分配执行引擎的资源给IDQ中的micro-ops,并移动micro-ops给执行引擎。
  • 重排序缓冲区(ROB):追踪所有执行中的micro-ops。(没有结果的指令将在ROB等待)
  • 统一保留站(URS):排队最大36条micro-ops直到操作资源ready,调度和分配ready的micro-ops到可用的执行单元。(没有数据的指令将在RS等待)
  • 内存重排序缓冲区(MOB):支持推测、乱序load/store,确保正确的次序和数据写回内存
  • 执行单元和操作数转发网络:每个时钟周期最多为一个micro-ops产生一个结果

在乱序执行架构中,不同的指令可能都会需要用到相同的通用寄存器(GPR,General Purpose Registers),为此Intel开始引入重命名寄存器(Rename Register),不同的指令可以通过具有名字相同但实际不同的寄存器来解决。

乱序执行从Allocator定位器开始,Allocator管理着RAT(Register Alias Table,寄存器别名表)、ROB(Re-Order Buffer,重排序缓冲区)和RRF(Retirement Register File,退回寄存器文件)。RAT将重命名的、虚拟的寄存器指向ROB或者RRF。RAT指向在ROB里面的最近的执行寄存器状态,或者指向RRF保存的最终的提交状态。当一条指令通过RAT发往下一个阶段确实执行的时候这条指令(包括寄存器状态在内)将被加入ROB队列的一端,在“乱序”之前,ROB的指令就已经确定了,指令并不是在ROB当中乱序挑选的(这在RS当中进行)。从执行单元返回的数据会将先前由调度器加入ROB的指令刷新数据部分并标志为结束(Finished),再经过其他检查通过后才能标志为完毕(Complete)。执行完毕的指令(包括寄存器状态)将从ROB队列的另一端移除(期间这些指令的数据可以被一些中间计算结果刷新),并提交寄存器状态。ROB担当的是流水线的最终阶段:一个指令的Retire回退单元;以及担当中间计算结果的缓冲区。提交状态的工作由Retirement Unit(回退单元)完成,它将确实完毕的指令包含的数据写入RRF(“确实”的意思是,非猜测执性、具备正确因果关系,程序可以见到的最终的寄存器状态)。RFF的数据最终先写入MOB(Memory Order Buffer,内存重排序缓冲区),再由MOB来完成写入L1D缓存。

猜测执行允许预先执行方向未定的分支指令。分支猜对了,其在ROB里产生的结果被标志为已结束,可以立即地被后继指令使用而不需要进行L1 Data Cache的Load操作。分支未能按照如期的情况进行,这时猜测的分支指令段将被清除,相应指令们的流水线阶段清空,对应的寄存器状态也就全都无效了。所以当指令和micro-ops在正确预测路径上才会发生状态的“Retirement”和“writeback”。Retirement处理满足以下两个条件:

1.与回退micro-op相关的所有micro-ops已经完毕”complete”,允许整条指令的Retirement。当一个指令的micro-ops的数量超大,填满回退窗口时,micro-ops可以回退。
2.正确预测路径上之前的指令的micro-ops已经发生回退。

这些保证处理器更新的状态与in-order执行的代码的micro-ops一致。

当之前的指令发生阻塞等待时,不会阻塞无依赖的新指令和micro-op执行。新指令的micro-ops将分配到执行单元,并且在ROB中等待执行完成。


Intel Nehalem arch


Inter Core i5

CPU Pipeline执行流程

  • 取指与解码(Front-End In-Order)

  • Instruction Fetch:将主存中的指令集合(4K左右)加载到L1的Instruction Cache中

  • Prefetch Buffer:从L1的指令缓存装载16Byte长度的指令到Buffer

  • Predecode & Instruction Length Decoder:将上过程中Buffer的指令进行指令长度解析(确定指令长度,解码指令前缀,为解码器标注指令类型等)以及进行分支预测的处理(确定分支指令的的跳转,使用BTB保存分支预测指令的地址)避免处理器在执行预测路径上的时候不会'"stalling"

  • Instruction Queue:将Predecode处理过后的指令进行指令对齐以及宏指令的融合(将可融合的指令送到解码器,生成新的指令,如比较判的分支X86指令集最终解码成单条micro Op,从而提升解码器的带宽,降低指令数量,提高运行效率)

  • Complex & Simple Decoder:将Instruction Queue中的指令进行解析,Complex Decoder负责解码复杂指令,将单条复杂的x86指令翻译成1-4条Micro Ops,Simple Decoder负责解码简单指令,将单条简单的x86指令翻译成1条类RISC指令的Micro Op

  • Decoded Instruction Queue:接收到了解码后的Micro Ops后,会经过Loop Stream Decoder以及Micro Instruction Sequencer

  • MicroOp Fusion:将多条Micro Ops进行融合,用于降低Micro Ops的数量,提高指令执行的吞吐量,以及Reorder Buffer的使用效率

  • 执行引擎(Out-Of-Order Executor)
    OOOE是为了直接提升ILP(Instruction Level Parallelism)指令集并行化的设计,在多个执行单元的超标量设计中,一系列执行单元可以同时执行一些没有数据关联性的若干指令,只有需要等待其他指令运算结果的数据会按照顺序执行。

  • 2 x Register Allocation Table:不同的指令可能都会需要用到相同的通用寄存器(GPR,General Purpose Registers),为了在这种情冲突的况下指令们也能并行工作,处理器需要准备解决方法。一般的RISC架构准备了大量的GPR,而x86架构天生就缺乏GPR(x86具有8个GPR,x86-64具有16个,一般RISC具有32个,IA64则具有128个),为此Intel开始引入重命名寄存器(Rename Register),不同的指令可以通过具有名字相同但实际不同的寄存器来解决(为了SMT同步多线程,这些寄存器还要准备双份,每个线程具有独立的一份)
    寄存器重命名避免了机器指令或者微操作不必要的顺序化执行,从而提高了处理器的指令级并行的能力。

  • ReOrder Buffer:只能存放128条指令,将寄存器重命名后的指令按照编程的原始顺序重新排序成一个队列,把打乱了次序的指令们依次插入队列中。

  • Reservation Station:指令保留站,等待源数据到来,以进行OOOE乱序执行,而没有数据的指令,则在Reservation Station中等待,直到等待到了数据后,通过各个端口发送到ALU中进行运算和执行,最终将运算数据通过MOB存入L1的数据缓存中,并且将结果通过Result Bus分发到ROB中,如果运算已经完成,则会更新ROB中的指令结果,并且从ROB中移除已经完成的指令,将该指令放到RRF中。除了存放指令之外,保留站的作用是监听内部结果总线上是否有保留站内指令所需要的参数。需要读取L1/L2缓存乃至内存的指令或者需要等待其他指令结果的指令必须在此等待

  • Retirement Register File:从ROB中移出一条指令就意味着指令执行完毕了,这个阶段叫做Retire回退,相应地ROB往往也叫做Retirement Unit(回退单元),并将其画为流水线的最后一部分。该部件存储了被提交的体系寄存器的状态,通过逻辑寄存器的号来查询这个寄存器堆,用于进行寄存器是否可用的标识,为寄存器重命名查询寄存器状态以便提供空闲寄存器。

重要部件

CPU中分为以下重要的部件:

  • PipeLine
  • 超标量&超线程
  • Hardware Prefetch:根据历史操作预先加载以后会用到的指令来提高性能
  • 分支预测(Branch Prediction)
  • Macro Ops && Micro Ops指令融合(MicroOp Fusion)
  • LSD
  • Register Allocation Table
  • ROB
  • RRF
  • MOB
  • Cache:L1,L2,L3缓存
  • L1:分为指令缓存(Instruction Cache,32K)以及数据缓存(Data Cache,32K):(N路集合关联)
  • L2:每个核超线程共享一个256K缓存(N路组相连(N Way Set-Associative))等
  • L3:所有核共用同一个8M的缓存
  • 多核CPU的总线:QPI

参考文献链接
https://upload.wikimedia.org/wikipedia/commons/6/64/Intel_Nehalem_arch.svg
https://www.cyningsun.com/06-01-2016/nehalem-arch.html
https://zhuanlan.zhihu.com/p/671129546

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号