CSAPP-04处理器体系结构

Posted by SH on May 8, 2020

CSAPP-04处理器体系结构

一个处理器支持的指令和指令的字节级编码称为它的指令体系结构(Instruction-Set Architecture,ISA),不同的处理器“家族”有不同的ISA。一个程序编译成在一种机器上运行,就不能在另一种机器上运行。

ISA在编译器编写者和处理器设计人员之间提供了一个概念抽象层,编译器编写者只需要知道允许哪些指令以及它们是如何编码的;而处理器设计者必须建造出执行这些指令的处理器。

处理器硬件的设计:一个硬件系统执行某种ISA指令的方式。

ISA模型看上去是顺序指令执行,但是,通过同时处理多条指令的不同部分,处理器可以获得更高的性能。

主要内容:

  • 定义一个简单的指令集Y86-64;
  • 数字硬件设计的背景,HCL(Hardware Control Language,硬件控制语言);
  • 基于顺序操作、功能正确但有点不实用的Y86-64处理器,每个时钟周期执行一条完整的Y86-64指令;
  • 流水线化的处理器(pipelined processor),每条指令分解成五步,每个步骤由一个独立的硬件部分来处理,处理器可以同时执行五条指令的不同阶段,需要处理冒险或冲突(hazard)情况;
  • 汇编器、模拟器。

Y86-64指令集体系结构

定义一个指令体系结构包括定义各种状态单元、指令集和它们的编码、一组编程规范和异常事件处理。

程序员可见的状态

每条指令都会读取或修改处理器状态的某些部分,这称为程序员可见状态。

image-20210111110521837

Y86-64指令

  • movq指令:irmovq、rrmovq、mrmovq、rmmovq,立即数(i)、寄存器(r)、内存(m);
  • 4个整数操作指令:addq、subq、andq、xorq,只对寄存器数据进行操作;
  • 7个跳转指令:jmp、jle、jl、je、jne、jge、jg;
  • 6个条件传送指令:cmovle、cmovl、cmove、cmovne、cmovge、cmovg;
  • call指令:将返回地址入栈,然后跳到目的地址;ret指令从这样的调用中返回;
  • pushq和popq:入栈和出栈;
  • halt:停止指令的执行。

image-20210111111316709

指令编码

image-20210111112544366

image-20210111112717738

指令集的一个重要性质就是字节编码必须有唯一的解释。保证处理器可以无二义性地执行目标代码程序。

Y86-64异常

image-20210111113359536

逻辑设计和硬件控制语言HCL

在硬件设计中,用电子电路来计算对位进行运算的函数,以及在各种存储器单元中存储位。

要实现一个数字系统需要三个主要的组成部分:

  • 计算对位进行操作的函数的组合逻辑;
  • 存储位的存储单元;
  • 控制存储单元更新的时钟信号。

逻辑门

And、OR、NOT:

image-20210111114210252

组合电路和HCL布尔表达式

组合电路:

  • 每个逻辑门的输入必须连接到下述选项之一:
    • 一个系统输入(称为主输入);
    • 某个存储器单元的输出;
    • 某个逻辑门的输出;
  • 两个或多个逻辑门的输出不能连接在一起,否则它们可能会使线上的信号矛盾;
  • 必须是无环的。

布尔表达式:两个输入a和b,唯一输出eq,当a和b都是1或都是0输出为1。

1
bool eq = (a && b) || (!a && !b);

image-20210111114757454

字级的组合电路和HCL整数表达式

image-20210111115001999

image-20210111115339754

集合关系

很多时候需要将一个信号与许多可能匹配的信号做比较,以此来检测正在处理的某个指令代码是否属于某一类指令代码。

例如:从一个两位信号code中选择高位和低位来为四路复用器产生信号s1和s0:

image-20210111115521493

存储器和时钟

组合电路从本质上讲,不存储任何信息。相反,它们只是简单地响应输入信号,产生等于输入的某个函数的输出。

为了产生时序电路(sequential circuit),也就是有状态并且在这个状态上进行计算的系统,必须引入按位存储信息的设备。存储设备都是由同一个时钟控制的,时钟是一个周期性信号,决定什么时候要把新值加载到设备中。

  • 时钟寄存器:存储单个位或字。时钟信号控制寄存器加载输入值。
  • 随机访问存储器(内存):存储多个字,用地址来选择该读或写那个字。

image-20210111124308192

Y86-64的顺序实现

将处理组织成阶段

通常,处理一条指令包括很多操作。将它们组织成某个特殊的阶段序列,即使指令的动作差异很大,但所有的指令都遵循统一的序列。每一步的具体处理取决于正在执行的指令。创建这样一个框架,能够设计一个充分利用硬件的处理器。

  • 取指(fetch):从内存读取指令字节,地址为程序计数器(PC)的值。
  • 译码(decode):从寄存器文件读入最多两个操作数,得到值valA和/或valB。
  • 执行(execute):算术/逻辑单元(ALU)要么执行指令指明的操作(根据ifun的值),计算内存引用的有效地址,要么增加或减少栈指针。得到的值称为valE。可能设置条件码。
  • 访存(memory):可以将数据写入内存,或者从内存读出数据,读出的值为valM。
  • 写回(write back):最多可以写两个结果到寄存器文件。
  • 更新PC(PC update):将PC设置成下一条指令的地址。

image-20210111135057814

SEQ硬件结构

image-20210111135409297

image-20210111135606829

SEQ的时序

image-20210111141121529

SEQ阶段的实现

流水线的通用原理

流水线化的一个重要特性就是提高了系统的吞吐量(throughput),不过它也会轻微地增加延迟(latency)。

计算流水线

image-20210111144649027

流水线的局限性

不一致的划分

image-20210111144938178

流水线过深,收益反而下降

image-20210111145102806

带反馈的流水线系统

相邻指令之间很可能是相关的,会引起错误。

image-20210111145317614

必须以某种方式来处理指令间的数据和控制相关,以使得到的行为与ISA定义的模型相符。

Y86-64的流水线实现

SEQ+:重新安排计算阶段

更新PC阶段在一个时钟周期开始时执行,而不是结束时才执行。

没有硬件寄存器来存放程序计数器,而是根据从前一天指令保存下来的一些状态信息动态地计算PC。这就是一个小小的证明——可以以一种与ISA隐含着的概念模型不同的方式来实现处理器,只要处理器能正确执行任意的机器语言程序。

SEQ到SEQ+中对状态单元的改变是一种很通用的改进例子,称为电路重定时(circuit )

image-20210111150307094

插入流水线寄存器

在SEQ+的各个阶段之间插入流水线寄存器,并对信号重新排列,得到PIPE-处理器。

  • F:保存程序计数器的预测值。
  • D:保存关于最新取出的指令的信息,即将由译码阶段进行处理;
  • E:保存关于最新译码的指令和从寄存器文件读出的值的信息,即将由执行阶段进行处理。
  • M:保存最新执行的指令的结果,即将由访存阶段进行处理。它还保存关于用于处理条件转移的分支条件和分支目标的信息。
  • W:反馈路径将计算出来的值提供给寄存器文件写,当完成ret指令时,还要向PC选择逻辑提供返回地址。

image-20210111150412162

对信号进行重新排列和标号

预测下一个PC

流水线化设计的目的就是每个时钟周期都发射一条新指令,也就是说每个时钟周期都有一条新指令进入执行阶段并最终完成。要做到这一点,必须在取出当前指令之后,马上确定下一条指令的位置。

如果取出的指令是条件分支指令,要到几个周期后,也就是指令通过执行阶段之后,才能知道是否要选择分支。类似地,如果取出的指令是ret,要到指令通过访存阶段,才能确定返回地址。

除了条件转移指令和ret以外,根据取指阶段中计算出的信息,能够确定下一条指令的地址。

通过预测PC的下一个值,在大多数情况下,能达到每个时钟周期发射一条新指令的目的。必须以某种方式来处理预测错误的情况。

猜测分支方向并根据猜测开始取指的技术称为分支预测

同条件转移不同,ret指令可能的返回值几乎是无限的,因为返回地址是位于栈顶的字,其内容可以是任意的。不会试图对返回地址做任何预测,只是简单地暂停处理新指令,直到ret指令通过写回阶段。

流水线冒险

  • 数据相关——数据冒险(data hazard):下一条指令会用到这一条指令计算出的结果;
  • 控制相关——控制冒险(control hazard):一条指令要确定下一条指令的位置,例如跳转、调用或返回指令。

用暂停来避免数据冒险

暂停时,处理器会停止流水线中一条或多条指令,直到冒险条件不再满足。

让一条指令停顿在译码阶段,直到产生它的源操作数的指令通过了写回阶段。

image-20210111152945657

用转发来避免数据冒险

PIPE-的设计是在译码阶段从寄存器文件中读入源操作数,但是对这些源寄存器的写有可能要在写回阶段才能进行。与其暂停直到写完成,不如简单地将要写的值传到流水线寄存器E作为源操作数。

加载/使用数据冒险

将暂停和转发结合起来。

避免控制冒险

异常处理

内部异常:

  • halt指令;
  • 有非法指令和功能码组合的指令;
  • 取指或数据读写试图访问一个非法地址。

PIPE各阶段的实现

流水线控制逻辑

性能分析

未完成的工作

  • 多周期指令
  • 与存储系统的接口