数字设计与计算机体系结构:第七章

241 阅读35分钟

第七章:微结构

1.引言

链接逻辑与体系结构的桥梁-微结构

微结构包括

  • 寄存器
  • ALU
  • 有限状态机
  • 存储器
  • 其他逻辑模块

同一微处理器结构(例如ARM)可以有不同的微结构:为在性能、成本、复杂性方面取得不同的折中

计算机体系结构状态和指令集

  • 体系结构

    • 指令集
    • 体系结构状态
  • ARM体系结构

    • 16个32位寄存器
    • 状态寄存器
  • 基于当前状态->执行一条特定指令->新的体系结构状态

  • 还可能包括非体系结构状态->简化逻辑或提升性能(就是一些其他的中间寄存器)

  • 以下考虑的是一个ARM指令系统的一个子集

    • 数据处理指令:ADD,SUB,AND,ORR(带寄存器和立即数寻址模式,但没有移位)
    • 存储器访存指令:LDR,STR(具有正立即偏移)
    • 分支指令:B

设计过程

  • 微结构两个互相关联的部分

    • 数据通路(以字为单位操作)

      • 存储器
      • 寄存器
      • ALU
      • 多路选择器
    • 控制单元

      • 控制数据通路如何执行这条指令->包括

        • 多路选择
        • 寄存器使能
        • 存储器写入
  • 设计方法

    • 从包含状态元件的硬件结构开始->包括

      • 存储器

      • 体系结构状态

        • 程序计数器
        • 寄存器
        • 状态寄存器
    • 在这些元件之间增加组合逻辑计算出新状态

    • 五个状态元件

      • 程序计数器

          - 逻辑上是寄存器文件的一部分,但它每个周期都被读写,与正常的寄存器操作无关
        
          - PC指向当前指令
          - PC'指向下一条指令的地址
        
      • 寄存器文件

          - 15个32位寄存器文件
        
          - R0~R14
          - 32位R15接收来自PC的R15寄存器值
          - 两个读端口A1,A2,RD1,RD2
          - 一个写端口A3,WD3数据输入端口
          - WE3写使能,mem->寄存器。在时钟上升沿将数据写入
          - CLK时钟
          - 读取R15返回PC+8,写入R15要单独处理以更新PC
        
      • 状态寄存器

          - FLAG
        
          	- NZCV
        
      • 指令存储器

          - A32位地址输入
        
          - RD 32位数据输出端口
        
      • 数据存储器

          - 单个读写端口
        
          - A地址
          - RD读出数据
          - WD写入数据
          - WE写使能
          - 写使能被置位,在时钟上升沿将WD数据写入A地址中,使能位0,则将地址读入RD
        
    • 指令存储器、寄存器文件、数据存储器在读出过程中都呈现出组合逻辑状态。写入时在时钟上升沿发生。地址、数据、和写使能都要满足建立时间、保持时间的要求

微结构

  • 三种ARM处理器微结构:

    • 单周期
    • 多周期
    • 流水线
  • 单周期

    • 在一个周期中执行一条指令

    • 易于解释

    • 控制单元简单

    • 由于其在一个周期内完成操作,所以不需要其他的非体系结构状态寄存器

    • 缺点

      • 时钟周期由最慢的指令决定
      • 处理器需要单独的指令和数据存储器,这通常是不现实的
  • 多周期

    • 利用多个较短的周期实现一条指令

    • 简单指令周期数少

    • 可以复用加法器、存储器

      • 同一个加法器可以在一条指令的不同周期中用于不同的目的
    • 需要增加一些非体系结构寄存器去保存中间结果

    • 多周期处理器在任意时刻仅执行一条指令

    • 每条指令需要多个周期

    • 多周期处理器只需要一个存储器,在一个周期内访问它以读取指令,在另一个周期访问它以读取或写入数据

    • 廉价系统的历史选择

  • 流水线

    • 将单周期结构流水线化
    • 在一个周期可以执行多条指令,某一时刻有多条指令
    • 显著提高了吞吐率
    • 必须添加逻辑处理指令之间的依赖关系,处理冲突
    • 还需要非体系结构的流水线寄存器
    • 必须在同一周期内访问指令和数据,所以需要单独的指令和数据高速缓存
    • 商用高性能处理器都是流水线结构

2.性能分析

简介

  • 特定的处理器有许多微结构

  • 具有不同的成本和性能平衡

    • 成本取决于硬件数量和实施技术
    • 精确的成本计算需要了解实现技术
    • 更多的门和更多的内存意味着更多的资金投入
  • 测量性能的最直接方式测试用户所需要程序的时间

    • 测量一组类似用户用户应用的程序集合的运行时间总和

    • 这样一组测试程序称为测试基准程序

    • 程序的执行时间(以秒为单位)

    • 指令数取决于

      • 处理器体系结构
      • 程序员的聪明才智
      • 指令所需周期数(CPI)是平均每条指令所需周期数
    • 时钟周期Tc

      • 由处理器中的的关键逻辑路径决定
    • 挑战

      • 最大程度减小程序执行的时间
      • 满足成本和功耗方面的限制
      • CPI与Tc都与微结构有关
    • 其他因素

      • 硬盘
      • 存储器
      • 图形系统
      • 网络连接等

3.单周期处理器

概述

  • 连接各状态元件形成数据通路

  • 控制信号决定在给定时间内需要由数据通路执行的特定指令

    • 包含根据当前指令产生合适控制信号的组合逻辑

单周期数据通路

  • 1.程序计数器包含要执行的指令的地址->从指令存储器读取该指令地址

  • 2.LDR指令实现

    • 第二步:读取包含基址的源寄存器Rn(Instr19:16)

    • 第三步:连接到寄存器文件读取端地址A1;读取到RD1上

    • 第四步:偏移量在Instr11:0中,它是无符号值,将其零扩展为32位

    • 第五步:基址加偏移得到读取存储器的地址

    • 第六步:得到ALUresult在存储器取出数据,写回到Rd寄存器WD3口:A3提供地址,RegWrite提供使能,ALUcontrol提供控制ALU执行00表示加法

    • 第七步:指令执行时处理器必须计算下一条指令的地址PC‘,下一条地址为PC+4

    • 第八步:将PC+8的值写入R15,PC’可能来自于指令ReadData(寄存器R15+立即数)故加一个选择器,PCSrc控制选择哪个PC'

  • 3.STR指令实现

    • 增加寄存器读通路,并将A2地址读到的数据RD2送到数据存储器写数据端口,MemWrite使能写数据WE,失能RegWrite

  • 4.具有立即数寻址的数据处理指令

    • ADD、SUB、AND、ORR这些指令都是从寄存器文件中读取源寄存器并且从指令的低位立即执行一些ALU操作,将结果返回第三个寄存器

    • ALUcontrol对于ADD为00,SUB为01,AND为10,ORR为11,并产生ALUFlags3:0,标志位,把他们发送回控制器

    • 再加一个立即数控制源ImmSrc来控制立即数的扩展多少位

    • 增加一个多路选择器,选择最终写回寄存器的结果是数据处理还是存储器写回

  • 5.具有寄存器寻址的的数据处理指令

    • 增加一个多路选择器和控制位来选择寄存器文件第二个源寄存器的来源:RegSrc
    • 增加一个ALU的源多路选择器,选择立即数或寄存器的数据:ALUSrc
  • 6.B跳转指令

    • 增加一个选择器,选择R15地址数据+立即数控制扩展为两位,选择PC‘的源为ALUResult

    • 立即数控制位编码

单周期控制

  • 控制单元根据指令的cond,op,funct(31:28,27:26,25:20),标志和目标寄存器是否为PC来计算控制信号

  • 控制器存储当前状态标志并对其进行适当更新

  • 控制器分为

    • 译码器

      • 产生大部分控制信号的主译码器
      • 根据功能字段确定数据处理指令类型的ALU译码器
      • 根据分支或写入R15以确定是否需要更新PC的PC逻辑
        - 主译码产生控制信号MemtoReg、ALUSrc、ImmSrc1:0直接到数据通路
      
        - RegW和MemW在成为数据通路信号RegWrite和MemWrite之前通过条件逻辑,如果条件不成立,则条件逻辑可以杀死这些使能
        - 分支和ALUOp用于指示该指令分别是B或数据处理
        - PC逻辑检查指令是写入R15还是分支,这样PC就应该更新,也可以被逻辑杀死
      
        	- 
      
        - 条件逻辑
      
        	- 是否应该根据cond字段执行命令(condEx),如果不应该执行,则写使能并且PCSrc被强制为0,指令不会改变体系结构状态。
        	- 当ALU译码器断言FlagW并且满足指令Condx=1时,条件逻辑还会更新ALUFlags中的部分或全部
      
    • 根据Instr生成控制信号

  • 条件逻辑、维护状态标志,只有在有条件低执行指令时才能更新体系结构状态

完整的单周期控制

单周期处理器操作

  • 确定控制信号的的值和数据通路的哪些部分在使用寄存器寻址模式执行ORR指令时使用

    • 加粗灰色表示通过寄存器文件和ALU的主要数据流。
    • 数据也流过未加粗的路线,但这些数据对指令并不重要,不影响系统的下一状态

更多指令

  • 增加指令原则

    • 用于寻址第二个源是移位寄存器的模式

    • 增加一些指令有些只需要增强译码器

    • 有些要增加新硬件

    • CMP指令

      • 增加一个NoWrite控制信号,以防止在比较期间写入Rd(此信号也能防止其他指令(如TST)写入寄存器),扩展ALU译码器来产生这个信号,并使RegWrite逻辑接收它的值,控制寄存器的写操作

    • 增强寻址模式:寄存器恒定的变化

      • 增加一个移位器

单周期性能分析

  • 单周期处理器每条指令都需要一个周期

    • 故CPI为1

    • LDR指令为例

      • 简化后
      • PC寄存器传输延迟+指令存储器延迟+译码延迟+读寄存器和多路选择或立即数扩展加多路选择器延迟+ALU计算单元延迟+数据存储器延迟+多路选择器延迟+写寄存器的建立时间
      • 绝大多数实现中ALU、存储器、寄存器文件都比其他组合块慢很多
      • 这些时间具体依赖特定的实现技术
    • 其他指令的关键路径都比较短,同步时序,周期为常数,应满足最慢指令的要求

    • 延迟

4.多周期处理器

简介

  • 单周期特点:

    • 单独的存储器用于指令和数据
    • 一个足够长的时钟周期来支持最慢的时钟周期指令(LDR)
    • 需要三个加法器
  • 实际情况是:

    • 一般数据和指令都存在一个存储器中
    • 时钟周期都比较快性能才高
    • 加法器比较昂贵
  • 多周期处理器

    • 将指令分解为多个步骤
    • 在每个步骤中,处理器完成存储器或寄存器文件的读或写操作或ALU操作=>指令和数据存储器可复用一个=>因为可在不同步骤中实现读取写入
    • 不同指令以不同步骤组合,这样简单指令可以较复杂的完成得快
    • 只需要一个加法器在不同步骤中用于不同目的
  • 设计多周期处理器

    • 建立状态原件数据通路,组合逻辑连接体系结构状态元件和存储器
    • 需加入非体系结构状态元件以保存每个周期的内部结果
    • 设计控制器对不同单条指令的每个指令周期产生不同的控制信号
    • 有限状态机而非组合逻辑实现生成控制信号
    • 如何添加新指令
    • 性能比价

多周期数据通路

  • 第一个周期根据PC从存储器取指->存在一个非体系结构的寄存器(IR)中,供后续周期使用。IRWrite使能位,在IR应该加载一个新指令时被置位

  • LDR指令

    • 读取基址源寄存器->Rn字段->Instr19:16->连接到寄存器文件A1地址->读出RD1存在非体系结构寄存器A中

    • 十二位立即数偏移量->字段Instr23:0->零扩展到32位称为ExtImm->ImmSrc控制扩展->组合逻辑,不用寄存器,在指令不变时不会改变

    • ALU计算基址和偏移量的总合->结果存在ALUout的非体系结构寄存器中

    • 根据地址取数据写回寄存器Rd->增加一个AdrSrc选择从PC或ALUout获得地址取数据->取出的数据放在Data数据寄存器中->AdrSrc必须在不同的步骤有不同的值

    • 数据写回寄存器->目标寄存器存在Rd段Instr15:12指定->增加一个多路选择器->选择从ALU或寄存器数据写回寄存器->RegWrite为1信号表示更新寄存器->ResultSrc选择写回寄存器的源

    • PC+4更新寄存器,可以在不使用ALU的步骤中使用ALU进行+4->ALU的源必须加多路选择器->增加两个选择器选择哪个可以被选->ALUResult也需被接入多路选择器PCWrite控制哪个周期更新PC

    • 读取R15返回PC+8->PC寄存器已经存有PC+4->再加4选择将ALU结果送到R15->读出就在写入周期的令半个周期,就看需不需要写入PC,需要数据通路走通才能更新PC->在指令的最后一步必须路由到PC寄存器

  • STR指令

    • 增加一个寄存器读取第二个寄存器并将其写入存储器->读取完存在非体系结构寄存器WriteData中MemWrite控制信号指示写发生

  • 数据处理指令立即数寻址

    • Rn读取第一个源->将8位立即数扩展成第二个源->对两个源进行操作->结果写回寄存器文件->ALUControl信号来确定要执行的数据处理指令的类型->ALUFlags被发送回控制器以更新状态寄存器
  • 数据处理指令寄存器寻址

    • 选择第二个源寄存器Rm=Instr3:0->增加多路选择器选择源RegSrc控制->扩展SrcB多路选择器接收从寄存器文件中读取的值

  • B分支指令

    • 分支读取R15返回PC+8+24位立即数,然后求和->将结果添加到PC->增加一个多路选择器到A1端->将读到的数据传给PC‘

多周期控制

  • 单周期控制单元根据指令的cond、op、和funct字段(Instr31:28、Instr27:26和Instr25:20)计算控制信号和标志,以及目的地寄存器是否是PC

    • 控制器存储当前状态标志并适当的进行更新
  • 包括

    • 译码器

        - 将单周期主译码器的组合逻辑换成MainFSM状态机->在适当周期上产生一系列控制信号。主FSM设计为Moore状态机
      
        - ImmSrc和RegSrc是op的函数而不是当前的状态
        - ALU译码器和单周期处理器中的相同
      
    • 条件逻辑快

        - 条件逻辑几乎与单周期相同
      
        - 计算PC+4时,增加了一个NextPC信号以强制写入PC
        - 将CondEx延迟一个周期->再将其发送到PCWrite、RegWrite、MemWrite以便在指令结束之前不会看到更新的条件标志
      
  • 完整多周期处理器

  • 主译码FSM

    • 产生

      • 多路选择器选择
      • 寄存器使能
      • 存储器写入数据通路的使能信号
    • 1.任何指令的第一步都是从PC寄存器中存储的地址处获取存储器中的指令,并将PC递增到吓一条指令

      • FSM在复位状态进入此取指状态

        • 数据流

        • 控制信号

    • 2.读取寄存器文件和立即译码

      • 基于RegSrc和ImmSrc选择寄存器和立即数->由Instr译码器基于Instr计算

      • RegSrc

        • 对于分支来说RegSrc0应该是1,读取PC+8作为SrcA。
        • 对于存储,RegSrc1应为1以将存储值读取为SrcB
      • ImmSrc

        • 数据处理指令00->选择8位立即数
        • 01用于加载和存储以选择12位立即数
        • 10用于分支以选择24位立即数
      • FSM(moore状态机不能根据输入决定输出)但可以用组合逻辑实现译码

      • 译码同时

        • ALU在取指步骤中的增加的PC上再加4来重新计算PC+8

        • 施加控制信号选择PC作为第一个ALU输入(ALUSrcA=1)

        • 4作为第二个输入(ALUSrcB=10)

        • 加法(ALUop=0)

        • 这个和被选择为结果提供给R15输入寄存器文件->使R15读取为PC+8

        • 译码步骤

          • 数据流

      • 接下来FSM进入几种可能的状态之一

        • 取决于->

          • Op
          • Funct
        • 如果是存储器加载或存储(LDR、STR,op=01)

          • 基址添加到零扩展偏移量来计算地址(ALUSrcA=0)

          • ALUSrcB=01来选择ExtImm

          • ALUOp=0

          • 有效地址存在ALUOut中以便下一步使用

          • LDR指令(Funct=1)

            • 从内存中读取数据写入寄存器文件

            • ResultSrc=00和AdrSrc=1来选择ALUout存储的地址

            • 在MemRead步骤中保存在数据寄存器中

            • 在写回步骤MemWB中将数据写入寄存器文件

            • ResultSrc=01从数据中选择结果

            • RegW被置位以写入寄存器文件

            • FSM回到取指状态以启动下一条指令

            • 对于MemAdr状态

              • STR(Funct=0)则从寄存器文件的第二个端口读取的数据只是写入内存

              • 在此MemWrite状态中

                • ResultSrc=00
                • AdrSrc=1
                • 选择在MemAdr状态下计算的地址并保存在ALUOut中
                • MemW被断言要写入内存,同样FSM返回取指状态
        • 数据处理指令Op=00

          • 使用ALU计算结果并写回寄存器
          • 第一个源始终来自寄存器(ALUSrc=0)
          • ALUOp=1->ALU译码器对于特定指令cmd选择适当的ALUControl
          • 第二个源来自寄存器文件(ALUSrcB=00)和或立即数(ALUSrcB=01)
          • 需要两种状态涵盖这两种情况ExecuteR和ExecuteI
          • 再转到写回状态ALUWB
          • ALUOut(ResultSrc=00)写入寄存器文件(RegW=1)
        • 分支状态

          • 计算目标地址PC+8+偏移写回PC寄存器
          • 译码状态->PC+8已经被计算并从寄存器文件读取到RD1上
          • 控制器选择ALUSrc=0来选择R15(PC+8)
          • ALUSrcB=01来选择ExtImm,并且ALUOp=0
          • ALUResult(ResultSrc=10)
          • 将结果写入PC
        • 完整图

性能分析

  • 指令的执行时间取决于它使用的周期数和周期时间

  • 多周期周期数多,但单个周期时间短

  • 不同的指令所需周期数不同

    • B三个周期
    • 数据处理指令和存储需要4个周期
    • 加载需要5个周期
  • CPI加权平均

  • 最坏情况所有指令都花费相同时间

  • 假设寄存器文件比内存更快且写入内存比读取内存更快->一条最慢的路径->PC->SrcA多路选择器->ALU->结果多路选择器->寄存器R15端口写入A寄存器

  • 2.从ALUOut通过结果多路选择器和地址多路选择器读取存储器数据写入数据寄存器

- 取决于实现技术
  • 多周期速度的慢于单周期处理器

    • 1.不是每一步都具有相同的长度
    • 2.每个周期必须增加90PS的寄存器CLK-TO-Q的时间和建立时间,而不是针对单条指令
  • 节省了加法器和存储器,但增加了寄存器和多路选择器

5.流水线处理器

简介:

  • 将单周期处理器分成5级以构成流水线处理器

  • 五条指令同时执行,大大提升了吞吐率,每级仅有整个逻辑的1/5,时钟频率几乎可以提高5倍

  • 引入了一些开销,所以不能达到5倍

  • 在整个处理器延迟中,存储器和寄存器文件的读写、ALU操作占用了很大延迟,我们选择5级流水线->使得每一级能完成一个操作

  • 五级分为

    • 取指

      • 根据PC从指令存储器读取指令
    • 译码

      • 从寄存器文件读取源操作数并对指令译码产生控制信号
    • 执行

      • ALU计算
    • 存储器访问

      • 从数据存储器读取或写入数据
    • 寄存器写回

      • 如果需要将结果写回寄存器文件
  • 单周期时序与流水线时序图比较

  • 流水线周期由最慢的一级决定,由于流水线级的划分不能完美的平均分配所有逻辑,因此流水线的延迟将稍长于单周期处理器

  • 吞吐率也不是完整的5倍,但已经显著提高

  • 抽象表示

      - 指令存储器(IM)
    
      - 寄存器文件读(RF)
      - ALU执行
      - 数据存储器(DM)
      - 寄存器文件写回
    
    • 沿着每一行读,可以确定某条指令在每一级中的周期数

      • SUB在第三周期取指,第五周期执行
    • 沿着每一列读,可以确定在特定时刻不同流水线级的操作

      • 在第六周期,ORR指令从指令存储器中取出,R1在读取寄存器文件,ALU计算R12和R13的与操作,数据存储器空闲->寄存器文件正在向R3写入和,每级流水线用阴影表示当前正在使用
      • 例如:数据存储器在第四周期中由LDR使用,第八周期由STR使用,指令存储器和ALU在每个周期都在使用;除了STR外,都需要写入寄存器文件
      • 寄存器文件在一个周期的第一部分写入,第二部分读取,此时,数据可以在一个周期完成写入和读取
  • 流水线的核心挑战是处理冲突->

    • 后条指令需要前条指令的计算结果,而前条指令还没有执行完毕时会发生冲突

    • 解决方法

      • 转发
      • 停顿
      • 冲刷

流水线数据通路

  • 将单周期处理器数据通路划分为5级

    • 流水线级和边界用灰色表示
    • F,D,E,M,W以标识他们属于哪一级
  • 寄存器文件比较特殊:

    • 它在译码级读取

    • 写回级写入

    • 把它画在译码级,但是写入地址和数据来自写回级

    • 寄存器文件在CLK下降沿写入

      • 前半部分写入,后半周期读取
  • 特定指令相关的所有信号必须在流水线中一起向前传播

  • 五个阶段

      - 将写回级数据写入了译码级地址发生错误->修改成
    
      	- 
    
      - PC更新逻辑也有问题->取指级和写回级信号进行更新(PCPlus4F或ResultW)
      - 取指级的PC+4,再过一个周期就是PC+8,也就是译码级需要的PC+8,所以可以直接将取指级的两个周期结果发送到译码级而节约一个加法器
    
  • 优化后的PC逻辑

流水线控制

  • 流水线处理器与单周期处理器使用相同的控制信号,因此可以使用相同的控制单元

    • 控制单元在译码级检查指令中的Op和Funct字段以产生控制信号,控制信号必须与数据一起流动,从而与指令保持同步
    • 控制单元还检查Rd字段以处理对R15(PC)的写入
  • RegWrite必须在送回寄存器文件之前通过流水线连接到写回级

冲突

  • 当一条指令依赖于还没有结束的指令时,将发生冲突

  • 寄存器文件可以在一个周期内完成读和写操作。这样寄存器可以在一个时钟周期内完成写入和读出而不发生冲突

  • 一条指令写入寄存器R1,后续指令读取这个寄存器,这时将产生冲突->写后读(read after write ,RAW)

  • ADD指令在第5个周期的前半部分向R1写入结果,AND需要在第三个周期读出,这将导致错误。

  • ORR指令在第四个周期读取R1,这也将导致错误。

  • SUB指令在第五个周期的后半部分读取R1寄存器的值,可以得到正确的值,因为第五个周期的前半部分已经写入,后续指令也可以得到正确地值

  • 流水线中当前一条指令需要写入寄存器时,后续两条指令读取这个结果时可能会发生冲突

  • 图形表示

冲突的解决方案

  • 数据冲突

    • 定义

      • 当一条指令试图读取前条指令还未写回的寄存器时,将发生数据冲突
    • 1.利用转发解决数据冲突

      • 一些冲突可通过存储器访问级或写回级的结果转发或旁路到执行级来化解

      • 需要在ALU前端增加多路选择器以选择来自寄存器文件中的操作数或来自存储器访问级和写回级的结果

      • 例子

        • 第四个周期,R1从ADD指令的存储器访问级转发到相关AND的执行级
        • 第五个周期,R1从ADD指令的写回级转发到相关的ORR指令的执行级
      • 当执行级的指令具有与存储器访问级或写回级中的指令的目标寄存器匹配的源寄存器时,转发是必要的

      • 增加一个冲突单元和两个转发多路选择器

        • 冲突单元从数据通路接受4个匹配信号,指示执行级的源寄存器是否与存储器访问级和写回级中的目标寄存器匹配

        • 不需要寄存器写入的不需要转发(STR和B),根据存储器访问级和写回级发送的RegWrite判断是否需要写回寄存器

        • 冲突单元多路选择器优先级逻辑

        • 例子

    • 2.利用停顿解决数据冲突

      • 当指令的结果在执行级计算时,可以用转发方法化解RAW数据冲突->因为结果可以转发到下一条指令的执行级->但是LDR指令直到存储器访问级后才能读取数据,因此结果不能转发到下一条指令的执行级,我们称LDR有两个周期延迟,因为相关指令直到两个周期后才能使用其结果

      • 例子

        • LDR指令在第四个周期的最后才从存储器中接收到数据,单数AND指令在第四个周期的开始时就需要这个数据作为源操作数,转发无法解决这个问题
      • 停顿流水线:将操作挂起直至数据有效

        - 在译码级停顿相关AND指令,该指令在第三个周期进入译码级并一直停顿到第四个周期位置->后续ORR指令也必须保持在取指级,因为译码级已经满了。
      
      • 停顿将产生气泡,但流水线停顿时应保持寄存器不变,前面各级也应该停顿->停顿后必须清除流水线寄存器以防止错误信息向前传播。停顿将降低性能,因此他们只有在必须时才能使用

      • 例子

          - 为LDR指令的数据依赖增加停顿功能,冲突单元将检查执行级中的指令=LDR且其目的寄存器匹配译码级中指令的任意一个源操作数,则指令必须停顿在译码级直至源操作数准备好
        
          - 停顿通过对取指级和译码级流水线增加使能(EN)和为执行级流水线寄存器增加同步复位/清除CLR的方式实现的。LDR停顿出现时,StallD和StallF信号有效,使取指译码流水线寄存器保持,FlushE有效清除执行级流水线寄存器中的内容,从而产生气泡。
          - 控制逻辑->MemtoReg信号变为有效
        
          	- 
        
  • 控制冲突

    • 定义

      • 当取指令时还未确定下一条指令应取的地址时,将发生控制冲突
    • 3.解决控制冲突

      • B指令将产生控制冲突

        • 写入R15也存在类似的冲突
      • 1.一种方式为停顿流水线直到确定分支是否发生为止->即PCSrcW被计算出来

      • 2.预测分支是否发生,并基于预测来执行命令

        • 预测错误->抛弃错误执行的命令

        • 浪费的指令周期称为分支误预测代价

        • 例子

          • 代价为四个指令周期
        • 改进->

          • 在执行级提前做出分支预测

            • 代价为两个指令
    • 修改了流水线处理器,以便更早的做出分支决策并处理控制冲突->

      • 在PC寄存器之前添加多路选择器以从ALUResult中选择分支目的地,控制该多路选择器的BranchTakenE信号在满足条件的分支上被断言。PCSrcW现在仅用于写入PC,这仍然发生在写回级
    • 计算停顿和冲刷信号来处理分支和PC写入

      • 分支

        • 必须从译码级和执行级流水线寄存器中冲刷后续两条指令
      • PC写入

        • 处于流水线中->应该停顿流水线直到写入完成->停顿取指级
        • 停顿流水线也需要冲刷下一个流水线以防止指令被重复执行
      • 例子

        • 当PC写入正在进行时(在译码、执行或存储器访问级),PCWrPending被置位,在此期间,停顿取指级并冲刷译码级,当PC写入到达写回级(PCSrcW置为有效)时,释放StallF以允许写入发生,但FlushD仍然有效,因此取指级中的非期望周期不会前进
      • 逻辑

  • 软件解决方案->插入NOP指令

    • 软件互锁使编程变得复杂
    • 降低了性能
  • 冲突总结

    • 定义:

      • 一条指令依赖于其他指令的结果,而此结果还未写入寄存器文件时将发生写后读(RAW)的数据冲突
      • 在取下一条指令时,还不能确定该如何取指,则发生控制冲突
    • 化解数据冲突的两种方法

      • 当结果已经计算出来时可以采用转发方法
      • 或停顿流水线直至结果可用
    • 化解控制冲突

      • 预测应取何种指令->

        • 预测错误冲刷流水线或停顿流水线做出决策
        • 尽量将分支确定过程提前以减少预测错误时冲刷的指令数目
      • 主要挑战是:理解指令间所有可能的相互关系并发现可能存在的所有冲突

    • 完整流水线处理器->处理了所有冲突

性能分析

  • 理想流水线CPI=1

  • 停顿冲刷浪费一个周期

  • 所需时间

  • 流水线处理器比其他处理器快

  • 对于单周期不是五倍加速->原因

    • 流水线冲突
    • 寄存器的时序开销clk-to-Q和建立时间对流水线每一级都有影响,而非整个数据通路
  • 增加了8个32位寄存器、多路选择器、更小的流水线寄存器和控制逻辑来解决冲突

6.硬件描述语言表示

7.高级微结构

简介

  • 程序运行时间正比于时钟周期和每条指令所需的周期数

  • 因此我们应提高时钟频率,同时降低CPI

  • 同时兼顾->

    • 速度
    • 功耗
    • 成本

深流水线

  • 流水线的最大级数受限于流水线冲突、时序开销、成本

    • 流水线越长->依赖性越高
    • 有一些依赖性可以通过转发解决
    • 另一些则必须要停顿流水线,增加CPI
  • 级数受限于->

    • 不同级流水线寄存器存在clk-to-Q延迟和建立时间的时序开销->包括时钟偏移
    • 需要额外的流水线寄存器和处理冲突的硬件->增加级数将增加成本

微操作

  • 通过定义一组可在简单数据通路上执行的简单微操作来快速处理常见情况->每个指令被译码为一个或多个微操作

  • 例子

分支预测

  • 理想流水线CPI为1,分支预测错误是增加CPI的主要原因

  • 流水线越深->分支的化解在流水线中就越迟->进而导致分支预测错误的开销越大

  • 因为分支预测错误->预测分支指令后发布的所有指令将被冲刷->采用分支预测器来猜测转移是否发生

  • 分支预测

    • 静态分支预测

      • 不依赖程序的执行历史,->循环时(for,while)检查分支方向->向后跳转的分支指令总会发生
    • 动态分支预测

      • 它使用程序运行的历史来预测分支是否发生

      • 动态分支预测器保持了处理器最近执行的上百条或上千条分支指令

      • 这个表往往称为分支目标缓冲->包含了分支目标和此分支是否发生的历史

      • 一位动态分支预测

        • 记住分支转移是否发生->并预测下一次也采取相同的动作
        • 总是会在循环的开始和结尾发生两次分支预测错误
      • 两位动态分支预测器

        • 通过四个状态来解决这个问题

          • 强跳转
          • 弱跳转
          • 弱不跳转
          • 强不跳转
        • 当循环重复->进入强不跳转->预测下一分支不跳转

        • 直到最后一次执行分支指令->转移到弱不跳转->当循环再次执行时->分支预测将不发生跳转->进入强不跳转状态

        • 总之,两位分支预测器仅在循环结尾处才会预测错误

    • 在流水线取指级运行->因此他可以确定下一周期需要执行哪条指令

      • 当预测发生->取出分支目标缓冲的分支目标指令
    • 典型程序->预测精度在百分之90以上

超标量处理器

  • 定义

    • 具有多个数据通路硬件以支持同时执行多条指令
  • 例子1->

    • 数据通路一次从指令存储器取出两条指令
    • 寄存器文件有六个端口
    • 每个周期中有4个端口用于读取源操作数,两个端口用于写回结果
    • 包含两个ALU,一个两端口数据存储器以同时执行两条指令
  • CPI为0.5,CPI倒数2=>每周期指令数

  • 超标量流水线操作示意图

  • 依赖性冲突问题

    • 转发
    • 停顿来解决
  • 超标量具有时间和空间并行两种形式

    • 时间并行->流水线
    • 空间并行->多个执行单元
  • 现在商业处理器已经有三路、四路甚至六路超标量结构

    • 但是程序依赖性往往很高->执行单元利用率低->转发和大量的执行单元需要消耗大量的电路和功耗

乱序处理器

  • 为解决依赖性问题->乱序处理器先检查多条指令是否可以发布->尽可能早地执行不依赖指令->则指令发布执行的顺序可以不同于程序员所写的顺序,只要保持依赖性就可得到正确的结果

  • 例子

  • 依赖性可以分为

    • 写后读

      • ADD指令和LDR指令对R8的依赖为写后读

        • 本质上限制了程序运行的速度
    • 读后写

      • SUB和ADD指令针对R8的依赖性为读后写冲突->反依赖

        • SUB不能不能在ADD之前写入R8
    • 写后写

      • 试图向后续指令已经写入的寄存器进行写入时

          - 乱序执行发生错误
        

寄存器重命名

  • 乱序处理器用寄存器重命名的方法消除WAR冲突

  • 在处理器中增加若干个非体系结构的重命名寄存器

  • T0~T19

    • 程序员不能直接使用,因为不是体系结构的一部分,但处理器可以自由使用消除冲突
  • 用一个表来记录哪些寄存器被重命名了->后续指令用到此寄存器也得用重命名的寄存器替换

多线程

  • 实际程序指令级并行性往往向当低

  • 存储器速度远低于处理器

    • 当高速缓存中没有命中,处理器将停顿上百个周期从主存中读取信息
  • 多线程技术可以在一个程序的指令级并行性比较低或者因存储器访问而停顿时->保持处理器中的多个执行单元处于有效工作状态

  • 一个应用程序称为进程

    • 一个进程拆分成并行线程程度决定了并行化水平TLP
  • 一个进程可以包含一个或多个同时运行的线程

  • 例如:

    • 字处理器程序中有一个线程用来处理用户输入
    • 另一个线程检查当前用户文档的拼写
    • 第三个线程负责打印

多处理器

  • 在一个芯片上重建了多个处理器副本,这些副本称为核

  • 多处理器系统由多个处理器和处理器之间的通信方法组成

    • 三种常见的多处理器

      • 对称(同构)多处理器
      • 异构多处理器
      • 集群
  • 对称多处理器

    • 包括俩个或多个相同的处理器

    • 共享一个存储器

    • 多个处理器可以是在同一芯片上的单独芯片或多个核

    • 可用于同时运行更多线程或更快地运行特定线程。同时运行更多线程很容易,线程只是在处理器之间的划分

    • 计算机设计人员和程序员面临的主要挑战之一是有效地使用大量处理器核

    • 设计简单->设计一次多次复制以提高性能

    • 编程执行代码简单->因为任何程序都可以在系统中的任何处理器上运行并获得大致相同的性能

    • 缺点

      • 普通程序在任意给定时间里只使用少量线程,而用户实际上希望几个应用程序同时运行
      • 除非程序开始显著整合更多并行化处理,否则继续增加处理器核好处会递减
      • 通用处理器的初衷是获得良好的平均性能
      • 不是某一操作的最节能选择
    • 多用于大量线程级并行性的大型数据中心

  • 异构多处理器

    • 通过整合不同类型的处理器核和专用硬件以在一个系统里解决上述问题每个应用程序选择那些为其提供最佳性能或最佳功率性能比的计算资源

    • 由于晶体管的资源丰富->将不同微结构的处理器核进行集成合并->这些核应用不同的功率、性能、面积的折中+

    • ARM推广的策略为big.LITTLE

      • 节能核

        • Cortex-A53

          • 单发或双发顺序处理器->处理日常任务
      • 高性能核

        • Cortex-A57

          • 超标量无无序内核->高性能
    • 另一种异构策略->加速器

      • 针对特定类型任务的能效优化的专用硬件

        • 图形处理
        • 视频
        • 无线通信
        • 实时任务
        • 密码技术
        • 等专用加速器
    • 缺点

      • 增加了系统复杂性
      • 无论是在设计还是编程还是资源调度方面
    • 适用于更多变化和特殊用途工作负载的情况

  • 集群

    • 每个处理器都有自己的本地内存系统
    • 一种是在网络软件上连接在一起的一组个人计算机->以共同解决大问题
    • 数据中心->计算机和磁盘机架联网在一起并共享电源和冷却设备

8.现实世界视角:ARM微结构的演变

ARM7框图

ARM9框图

Cortex-A9框图

Cortex-A7和Cortex-A15框图

9.总结

实现了单周期、多周期、流水线的ARM处理器微结构

具有相同的体系结构状态->实现了相同的ARM指令子集

单周期CPI=1

多周期使用较短的变长步骤来执行命令;同时可重用ALU

  • 需要非体系结构寄存器
  • 理论上更快
  • 受限于最慢步骤和时序开销

流水线处理器分割并行执行五条指令->理论CPI=1,但冲突导致的停顿和流水线冲刷会稍微增加CPI

  • 需要冲突控制单元

本章假设存储器是理想的,但不是

本章思维导图

第七章:微结构.png