《深入理解计算机系统(第三版)》第四章

4.1 Y86-64 指令集体系结构

1.指令体系结构:处理器支持的指令和指令的字节级编码。

2.与 X86-64 相比,Y86-64 指令集的数据类型、指令和寻址方式要少一些,字节级编码也比较简单,机器代码没有 Y86-64 紧凑,虽简单但足够完整。

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

4.Y86-64 有8个程序寄存器:%rax,%rcx,%rdx,%rbx,%rsi,%rdi,%rsp,%rbp 和 %r8 到 %r14(少了 %r15)。%rsp 被入栈、出栈、调用和返回指令作为栈指针,其它寄存器没有固定的含义或固定值。

5.下图是 Y86-64 指令集。指令编码长度从1~10个字节不等。字段 fn 指明是某个整数操作(OPL)、数据移动条件(cmovXX)或分支条件(jXX)。

  • 除了不允许从内存传到内存,还不允许将立即数传送到内存
  • OPq 是 addq、subq、andq、xorq,只对寄存器数据进行操作,而 X86-64 还允许对内存数据进行此类操作
  • jXX代表 jmp、jle、jl、je、jne、jge、jg。

6.每条指令的第一个字节表面指令的类型。本字节分为两部分,高4位是代码部分,低4位是功能部分。rrmovq 与条件传送的指令代码都为2,可以把它看作是一个“无条件传送”。

15个程序寄存器中每个都有一个相对应的范围在0

~0xE之间的寄存器标识符。程序寄存器存在CPU中的寄存器文件(以寄存器id作为地址的随机访问存储器)中,当需要指明不应访问任何寄存器时用 0xF 表示。

7.没有寄存器操作数的指令(分支指令和call指令)没有寄存器指示符字节;只需要一个寄存器操作数的指令(irmovl,pushl,popl)将另一个寄存器指示符设为0xF;有些指令需要附加的4字节常数字,可作 irmovl 的立即数数据,rmmol 和 mrmovl 的地址指示符的偏移量、分支指令和调用指令的目的地址。注意: 分支指令和调用指令的目的地址是一个绝对地址,所有整数采用小端法编码

8.rmmovq %rsp,0x123456789abcd(%rdx)中偏移量要放在8字节的常数字中,所以得先填充0变成8字节,然后再按反序输出,最后字节编码为 4042cdab896745230100。

9.状态码 Stat 描述程序执行的总体状态。ADR 表示处理器试图从一个非法内存地址读或者向一个非法内存地址写。INS 表示遇到了非法的指令代码。

  1. x86-64 和 Y86-64 由 GCC 编译器产生的代码有不同:
  • Y86-64 将 常数加载到寄存器,因为它在算术指令中不能使用立即数
  • 实现从内存读取一个数并将其与一个寄存器相加,Y86-64 代码需要两条指令(先放到寄存器中再加),而 x86-64 只需要一条 addq 指令
  • Y86-64 实现 subq 指令同时还设置了条件码

11.pushq %rsp压入 %rsp 的原始值,popq %rsp将 %rsp 设置为从内存中读出来的值。

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

1.数字系统需要三个主要组成部分:

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

2.C语言中符号运算符的逻辑门下面是对应的HCL表达式:AND用&&表示,OR用||表示,而NOT用!表示。逻辑门只对单个位的数进行操作。逻辑门总是活动的,输入变化输出很快就跟着变化。

用HCL来写这个网的函数:bool eq = (a && b) || (!a && !b)

多路复用器(根据s的值选择是输出a或者b)用HCL来描述:out = (s && a) || (!s && b)

3.将很多的逻辑门组合成一个网,就能构建计算块,称为组合电路。构建这些网时,两个或多个逻辑门的输出不能连在一起且这个网必须是无环的。通常设计的是能对字进行操作的电路:

在HCL中,所有字级的信号都声明为int,不指定字的大小。此电路的函数在字级上表达成 bool Eq = ( A == B )

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

此电路中,两位信号code可控制对4个数据字A、B、C、D做选择,根据code值,可以用相等测试来表示信号 s1 和 s0 的产生:bool si = code in { 2, 3 };bool s0 = code in { 1, 3 };

5.组合电路本身不能存储信息。为了产生时序电路,必须引入按位存储信息的设备。一类是时钟寄存器(简称寄存器),储存单个位或字。另一类是随机访问储存器(简称储存器):储存多个字,用地址选择该读/写哪个字,例子包括处理器的虚拟内存系统和寄存器文件。

6.寄存器文件有内部存储,不是组合电路。有A、B两个读端口,和一个W写端口。允许同时进行多个读写操作,可以同时读两个寄存器,同时更新第三个寄存器的状态。两个读端口有地址输入srcA、srcB和数据输入valA和valB。写端口有地址输入dstW,数据输入valW。向寄存器文件写入字是由时钟信号控制的,每次时钟上升时,输入valW上的值会被写入输入dstW上的寄存器ID指示的程序寄存器。

7.随机访问存储器从内存中读的操作方式类似于组合逻辑,写内存时由时钟控制的。

4.3 Y86-64的顺序实现

1.处理一条指令包含很多操作,将它们组织成某个特殊的阶段序列。分为以下几个阶段:

  • 取指:取指阶段从存储器读取指令字节,地址为程序计数器(PC)的值
  • 译码:译码阶段从寄存器文件读入最多两个操作数,得到val A 和 / 或 val B
  • 执行:执行阶段,算术/逻辑单元要么执行指令明确的操作(根据ifun的值),计算存储器引用的有效地址,要么增加或减少栈指针。得到的值为valE
  • 访存:访存阶段可将数据写入存储器或从存储器读出数据
  • 写回:最多可写两个结果到寄存器文件
  • 更新PC:将PC设置成下一指令的地址

2.以下是各个 Y86-64 指令在顺序实现中的计算:

jXX Dest在执行阶段,检查条件码和跳转条件来确定是否要选择分支,产生出一个一位信号 Cnd 。在更新 PC 阶段,检查这个标志,如果标志为1,就将PC设为valC(跳转目标),如果为0,就设为valP(下一条指令的地址)。

3.我们要将上述计算映射到硬件上,就是要实现逻辑控制,它能在不同硬件单元之间传送数据,以及操作这些单元,使得对每个不同的指令执行指定的运算。SEQ 硬件结构中灰色圆角方框表示的就是控制逻辑块:

4.要控制处理器中活动的时序,只需要寄存器和内存的时钟控制。通过时钟周期来控制元素的更新,通过组合逻辑来传播,每次时钟周期由低到高时,处理器开始执行一条新指令。处理器从来不需要为了完成一条指令的执行而去读该指令更新了的状态。

4.4 流水线的通用原理

1.非流水线化的硬件系统:

2.流水线化的硬件系统:

流水线阶段之间的指令转移是由时钟信号来控制的。每隔120ps信号从0上升至1,开始下一组流水线阶段的计算。

3.流水线的局限性:

  • 不一致的划分:由于阶段的延迟并不一样,这样空闲的空间就增加了延迟
  • 流水线过深,收益反而下降

4.5 Y86-64 的流水线实现

1.对 SEQ 中五个阶段的顺序进行调整,使得更新 PC 阶段在一个时钟周期开始时执行,而不是在结束时才执行。这种修改过的设计为“SEQ+”。SEQ+中没有单独的硬件寄存器来存放pc,而是通过pIconde、pCnd等寄存器(保存的是前一个周期中产生的控制信号),在一个新的时钟周期开始时用同样的逻辑来计算 pc 值。

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

  • F : 保存pc预测值
  • D :位于取指和译码之间,保存最新的指令信息,即将由译码阶段处理
  • E :位于译码和执行之间,保存最新译码指令和从寄存器读出的值,即将由执行阶段处理
  • M :位于执行和访存之间,保存最新执行指令的结果,条件分支和分支目标,即将由访存处理
  • W :位于访存和反馈之间,提供给寄存器文件写,完成ret指令,向pc提供返回地址

3.D_stat、E_stat、M_stat、W_stat指的是流水线寄存器的状态码字段,而小写的 f、d、e、m、w指的是流水线阶段,是为了引用某些在一个阶段内刚刚计算出来的信号。

4.数据相关和控制相关可能会导致流水线产生计算错误,成为冒险。首先关心数据冒险,然后再考虑控制冒险。

5.避免数据冒险的方法:

  • 暂停:将指令阻滞在译码阶段,相当于加入一条nop指令,直到产生它的源操作数指令通过了写会阶段。

  • 转发:将结果值直接从一个流水线阶段传到较早阶段。不是在被动的等待 irmovq 执行完毕,而是在addq指令需要用到rax值时将 irmovq 的W阶段的中间值 W_valE 转发到 addq 指令中作为源操作数 valB :

  • 使用暂停和转发相结合的方法来避免加载/使用数据冒险。

6.异常处理方法:

  • 由流水线最深的指令引起的异常,优先级最高
  • 多条分支中有异常,取消预测指令
  • 根据状态码stat发现异常,禁止其他指令更新程序状态

7.PIPE 是使用了转发技术的流水线化的 Y86-64 处理器:

  • PC选择和取指阶段:当预测错误分支进入访存阶段,PC选择逻辑会选择M_valA中读出该指令valP的值(下一条指令的地址);当ret指令进入写回阶段时从W _valM中读出的返回地址;其他情况下选择F_predPC。

  • 译码和写回阶段:提供给写端口的寄存器ID来自于写回阶段(W_dstE和W_dstM),而不是译码阶段。“Sel+Fwd A”实现 select A 和对 valA 的转发逻辑,“Fwd B”实现对 valB 的转发逻辑:

  • 执行阶段:

  • 访存阶段:PIPE 中用“Sel+Fwd A”执行SEQ中的“Data”块:

8.流水线控制逻辑根据来自流水线寄存器和流水线阶段的信号,控制逻辑产生流水线寄存器的暂停和气泡控制信号,同时也决定是否要更新条件码寄存器。PIPE流水线控制逻辑覆盖了通过流水线的正常指令流,以处理特殊条件,例如过程返回、预测错误的分支、加载/使用冒险和程序异常:

9.通过确定往流水线中插入气泡的频率来衡量效率的损失。一条返回指令会产生三个气泡,一个加载/使用冒险会产生一个,一个预测错误的分支会产生两个。通过计算PIPE执行一条指令所需要的平均时钟周期数的估计值来量化处罚对整体性能的影响(CPI)。CPI = 1.0 + lp + mp + rp

算出CPI的值为1.27。我们的目标是设计一个每个周期发射一条指令的流水线,即CPII为1.0。要想降低CPI,要集中注意力预测错误的分支

10.实现多周期指令可以简单扩展执行阶段逻辑的功能,添加一些整数和浮点算术运算单元;用暂停来处理短时间的高速缓存不命中和用异常处理来处理长时间的缺页结合起来能够顾及到存储器访问时由于存储器层次结构引起的所有不可预测性。

原文地址:https://www.cnblogs.com/Jspo/p/8459833.html

时间: 2024-11-06 13:38:28

《深入理解计算机系统(第三版)》第四章的相关文章

Python学习笔记_Chapter 4数据保存到文件

1. What For 将基于内存的数据存储到磁盘上,达到持续存储. 2. HOW 方法一: 将数据写到文件中 常规的处理方式 1 #file.x被打开的文件,model打开文件的方式 2 out=open('file.x','model') 3 #print将item写入到file指示的文件中,item可以是字符串或列表等 4 print(item,file=out) 5 #close是必须的,起到刷新输出的作用 6 out.close() open('file','model')中model

系统分析员考试复习笔记-4:第四章 数据通讯与计算机网络

 1.      第四章数据通讯与计算机网络(P143) 计算机网络源于计算机技术与数据通讯技术的结合,它通过网络链路将分布在各个地理位置的多台独立的计算机相互连接起来,从而形成一种网络,并在网络操作系统.网络管理软件和网络通讯协议的管理和协调下,实现资源(硬件.软件和数据)共享. 1.1.      数据通讯基础知识 1.1.1.     信道特性 各种数据终端设备交换数据,必然要传输数据(模拟信号或者数字信号),数据传输的路径称为信道.信道可以分为物理信道和逻辑信道.物理信道由传输介质和

第四章《数据保存到文件》

知识点: stript():去除空白字符 print()保存 代码: try: with open('its.txt','w') as data: print("it's...",file=data) except IOError as err: print('file error: '+str(err)) man=[]other=[]try: data = open('sketch.txt') for each_line in data : try: (role,line_spoke

【数据分析 R语言实战】学习笔记 第四章 数据的图形描述

4.1 R绘图概述 以下两个函数,可以分别展示二维,三维图形的示例: >demo(graphics) >demo(persp) R提供了多种绘图相关的命令,可分成三类: 高级绘图命令:在图形设备上产生一个新的图区,它可能包括坐标轴.标签.标题等. 低级绘图命令:在一个己经存在的图形上加上更多的图形元素,如额外的点.线和标签. 交互式图形命令:允许交互式地用鼠标在一个已经存在的图形.上添加图形信息或者提取图形信息. 使用R语言作图,主要按照以下步骤进行: ①取原始数据,准备好绘图需要的变量. ②

如何将前端数据保存到文件

有时候,网页上需要提供将当前页面上的数据导出为本地文件的功能,例如将页面上的一个表格导出为csv文件.这个功能看似简单,实际上却没有什么直接的方法.由于导出文件的操作(比如浏览文件目录,创建本地文件等)已经超出了浏览器内JS解释器的职责范围,需要和操作系统交互了,所以如果没有浏览器提供接口支持,是没法导出文件的.但是,有一个巧妙的办法,就是使用<a>元素(https://stackoverflow.com/questions/13405129/javascript-create-and-sav

Python 脚本生成测试数据,Python生成随机数据,Python生成大量数据保存到文件夹中

代码如下: import random import datetime import time dataCount = 10*100*100 #10M. codeRange = range(ord('a'),ord('z')) alphaRange = [chr(x) for x in codeRange] alphaMax = len(alphaRange) daysMax = 42003 theDay = datetime.date(1900,1,1) def genRandomName(n

把BitmapSource图片数据保存到文件

实现函数: /// <summary> /// 保存图片到文件 /// </summary> /// <param name="image">图片数据</param> /// <param name="filePath">保存路径</param> private void SaveImageToFile(BitmapSource image, string filePath) { BitmapE

补基础:自学:计算机科学导论 第四章 数据运算

4.1 逻辑运算:指那些应用于模式中的一个二进制位,或在两个模式中相应的两个二进制位的相同基本运算. 4.1.1 位层次上的逻辑运算 0 代表逻辑 假, 1 代表逻辑 真. 4种操作: 非(NOT):只有一个输入 如果输入是0, 则输出为1.反之亦然 应用:对整个模式求反 与(AND)有两个输入 如果输入都是1, 则输出为1.输入中只要有一位是0,则结果为0 应用:把一个位模式的指定位复位(置0).这种情况下,第二个输入称为掩码,掩码中的0位对第一个输入中相应的位进行复位. 或(OR)有两个输入

php导出csv数据在浏览器中输出提供下载或保存到文件的示例

来源:http://www.jb51.net/article/49313.htm 1.在浏览器输出提供下载 /** * 导出数据到CSV文件 * @param array $data 数据 * @param array $title_arr 标题 * @param string $file_name CSV文件名 */ function export_csv(&$data, $title_arr, $file_name = '') { ini_set("max_execution_tim

Head First Python 第二章 函数模块&amp;第三章 文件与异常&amp;第四章 持久存储&amp;第五章 处理数据

第三章 1.共享模块 模块和发布工具箱全世界共享模块 编写函数,以.py为文件后缀名,第三方库都在PyPI *注释代码:三引号(单双都可以) 发布过程P40 使用发布工具,函数模块变成了一个“发布”,可以使用import导入其他程序 2.如果函数模块功能不满意 添加参数以供api选择比添加函数工作量小! 首先考虑BIF内置函数 ----------------------------------------------------------- 第四章 1.文件 open()语句,readlin