我们熟知的编程语言C、java、脚本语言等,都是按照顺序执行的,前面提及过的文章中,机器代码也是按照顺序执行的,但是从机器硬件的实现上,近代处理器执行指令的顺序并不是我们所看到的顺序执行,然而,却能保证指令顺序执行的结果。

前提知识:

1.机器指令是二进制格式的代码,以字节为单位的一个或多个的字节序列。

2.指令集体系结构(ISA):一个处理器支持的指令和指令的字节编码。不同的处理拥有不同的指令集体系结构(Intel IA32与x86-64)。因此,一个程序被编译在一个机器上运行,就不能在另外的机器上运行!

图一,指令代码表示

指令的顺序实现

通常,处理一条指令包括很多操作。将它们组织成某个特殊的阶段序列,即时指令动作差异很大,但所有的指令都遵循统一的序列。所有的指令动作都可以囊括为以下五个阶段:

取值:取值阶段从内存读取指令字节,地址为程序计数器(PC)的值。从指令中抽取出指令指示符字节的两个四位部分,称为icode(指令代码)和ifun(指令功能)。它可能取出一个寄存器指示符字节,指明一个或两个寄存器操作数指示符rA和rB。

译码:译码阶段从寄存器文件读入最多两个操作数,得到值valA和/和valB。通常,它读入指令rA和rB字段指明的寄存器,不过有些指令是读寄存器%rsp的。

执行:在执行阶段,算术/逻辑单元(ALU)要么执行指令指明的操作,计算内存引用的有效地址,要么增加或减少栈指针。得到的值我们成为valE。在此,也可能设置条件码。对一条条件传送指令来说,这个阶段会检验条件码和传送条件(由ifun给出),如果条件成立,则更新目标寄存器。同样,对一条跳转指令来说,这个阶段会决定是不是应该选择分支。

访存:访存阶段可以将数据写入内存,或者从内存读出数据。读出的值为valM。

写回:写回阶段最多可以写到两个结果到寄存器文件。

更新PC:将PC设置成下一条指令的地址。

任何一条简单的指令都可以按照上述的步骤完成一个周期,(下图表明寄存器文件与内存数据的读写是由时钟周期控制的,图中上凸的形状表明,此时寄存器文件处于不能修改的状态。)

上述的简单指令的顺序实现,通过将执行每条不同指令所需的步骤组织成一个统一的流程,就可以用很少量的各种硬件单元以及一个时钟来控制计算的顺序,从而实现整个处理器。不过这样一来,控制逻辑就必须要在这些单元之间路由信号,并根据指令类型和分支条件产生适当的控制信号。

但是,这要求每个阶段必须等待上一个阶段的完成,下一个指令的寄存器状态需要等待上一个指令的寄存器值的更新,这就不能充分利用硬件单元的所有时间,从另外一个角度来看也不符合实际的利用二进制流控制硬件的实现,二进制流是高低电压的连续表示。

流水线的实现

a).指令的顺序实现

b). 流水线实现

从顺序实现到流水线实现,其实就是把顺序实现的过程里面拆分出更小的阶段。图b中可看出,指令I1完成A阶段进入B阶段时,I2同时开始A阶段。那么组合逻辑A硬件就能够得到充分的利用。

影响流水线的效率的因素有以下两个:

1、组合逻辑不一致的划分,也即组合逻辑A的延迟时间与组合逻辑B的延迟时间大小悬殊

2. 流水线过深,也即组合逻辑之间的保存状态的寄存器的数量太多,组合逻辑被划分成过分的小部分,影响了实际需要执行的内容。

流水线的数据相关

但是,我们很容易会产生以下的疑问:如果I2的A阶段依赖I1中C阶段的结果(下一条指令的寄存器状态依赖上一条指令的计算结果),那么怎么确保信息对称?

因此需要带反馈的流水线实现!表达每对相邻指令之间的数据相关。

对比上述的流水线实现,带反馈的流水线系统需要在指令的每一个阶段都加入流水线寄存器,保存该阶段的状态信息。另外,需要将更新PC操作,放到取指阶段,具体方法是:创建新的寄存器保存一条指令执行过程中计算出来的信号,然后在新的时钟周期开始时(新的指令执行时),利用上一条指令保存的信号通过同样的逻辑计算当前指令的PC值。

流水线寄存器的负责如下的信息保存,当我们执行一条新的指令时,这些流水线寄存器分别有F、D、E、M、W,它们的功能如下:

F:保存程序计算器的下一条指令的地址的预测值,也即下一条PC值;

D:位于取指与译码阶段之间。它保存关于最新取出的指令和从寄存器文件读出的值的信息,即将由执行阶段进行处理。

E:位于译码和执行阶段之间。它保存关于最新译码的指令和从寄存器文件读出的值的信息,即将由执行阶段进行处理。

M:位于执行和访存阶段之间。它保存最新执行的指令的结果,即将由访存阶段进行处理。它还保存关于用于处理条件转移的分支条件和分支目标的信息。

W:位于访存阶段和反馈路径之间,反馈路径将计算出来的值提供给寄存器文件写,而当完成ret指令时,它还要向PC选择逻辑提供返回地址。

在这里,我们如果要实现流水线,那么我们在执行当前指令的同时必须要预测下一条PC的值,对于普通情况,下一条PC的值可以简单地从二进制流中得到。但是对于条件分支指令,我们必须执行完结果后,才能知道下一条应该执行的指令的地址,这种情况,会采取之前的文章中提及的分支预测操作。

流水线冒险

上述需要预测下一条指令PC值的解决方法,这里将要讨论控制相关的策略,如何解决数据相关的问题。控制相关指,一条指令要确定下一条指令的位置,例如在执行跳转、条用或返回指令时。这些相关可能会导致流水线产生计算错误,称为冒险。同相关一样,冒险分为两类:数据冒险和控制冒险。

图中是典型的数据相关的例子,即将要执行的指令需要前面计算后的值,但是流水线的过程,让前面的指令仍未计算好后面需要的值

解决这种数据相关的问题,就需要数据冒险,可以使用如下的方法:

1.用暂停来避免数据冒险

暂停是避免冒险的一种常用技术,暂停时,处理器会停止流水线中一条或多条指令,知道冒险条件不再满足。让一条指令停顿在译码阶段,直到产生它的源操作数的指令通过了写回阶段。(如上图,当把addq指令阻塞在译码阶段时,我们还必须将紧跟其后的halt指令阻塞在取指阶段。通过将程序计数器保持不变就能做到这一点,这样一来,会不断地对halt指令进行取指,知道暂停结束)

2.用转发来避免数据冒险

与其暂停直到写完成,不如简单地将要写的值传到流水线寄存器E、M、W作为源操作数。如下图

a)

b)

c)

上述三图表示利用流水线寄存器的值充分利用了转发技术,实现了数据冒险。图c)表示了ALU逻辑处理单元是不存在时序问题的。e_valE的值是在取指阶段就完成了。并把值存放在流水线寄存器中。

3.加载/使用数据冒险

有一类数据冒险不能单纯用转发来解决,因为内存读在流水线发生的比较晚。如下图所示:

我们可以将暂停和转发结合起来,避免加载/使用数据冒险。上图所示,只要周期7延迟一个周期到周期八,就可以利用转发技术,因此。我们可以将译码阶段中的指令暂停一个周期,导致执行阶段中插入一个气泡。

避免控制冒险

上述的加载/使用数据冒险很好的解决数据关联时,怎么实现流水线的假设。当处理器无法根据处于取指阶段的当前指令来确定下一条指令的地址时,就会出现控制冒险。

TODO:编写下面的内容 339...

处理器的流水线式实现相关推荐

  1. 【计算机组成原理】流水线式指令执行

    文章目录 前言 一.处理器的构成 二.数据通路 1. 流水线工作 2. 冒险 3. 流水线寄存器 三.FPGA相比于CPU的速度优势 总结 前言 最近在阅读<计算机组成与设计 硬件/软件接口(原 ...

  2. 华为云软件开发平台(DevCloud)流水线式部署Vue项目,并且通过域名访问

    一.准备环境 1.1.华为弹性云服务器(ECS)或者云耀云服务器(HECS) 1.2.软件开发平台(DevCloud) 1.3.容器镜像服务(SWR) 1.4.云解析服务(SWR) 二.软件开发平台( ...

  3. 软件开发,标准化流水线式开发的实施构想

    软件开发,标准化流水线式开发的实施构想 原文链接: https://yq.aliyun.com/articles/258801?spm=a2c4e.11153940.0.0.7fc9653c6s1Cm ...

  4. 【组成原理-处理器】流水线技术

    文章目录 0 流水线性能指标 0.1 指令执行时间 0.2 流水线的吞吐率 0.3 流水线的加速比 0.4 流水线的效率 1 基本流水线技术 1.0 流水线设计基本原则 1.1 五段流水线 1.1.1 ...

  5. 带你了解嵌入式处理器的流水线技术

    ​01.为什么要引入流水线技术 嵌入式处理器执行指令时,一般步骤为:首先从存储器中读取指令,然后对该指令进行译码,识别出被执行的指令属于哪一种指令,然后再从指令中提取到操作数并进行组合,接着根据需要将 ...

  6. mips的旁路_64位MIPS指令处理器的流水线设计

    1 引言 随着集成电路设计和工艺技术的发展,嵌入式系统(SOC)已经在PDA.机顶盒.手机等信息终端中被广泛应用.他不仅减小了电路尺寸,而且具有成本低廉,可靠性高,功耗低等优点.可以说嵌入式系统是未来 ...

  7. Fig (无花果)任务流水线式 多线程框架使用

    介绍 Fig 是为了简化多线程开发和多台服务器间实现数据多流水线运行的平台(需要redis进行多服务器的数据共享)通过Fig可以加快数据的处理速度 尤其适合开发多线程爬虫程序 Fig 在开发多线程程序 ...

  8. 【机器学习算法实践】AdaBoost是典型的Boosting算法,加法模型多个弱分类器流水线式的提升精度,更关注那些难处理的数据

    现实生活中,大家都知道"人多力量大","3 个臭皮匠顶个诸葛亮".而集成学习的核心思路就是"人多力量大",它并没有创造出新的算法,而是把已有 ...

  9. 设计一个简易的处理器(8)--流水线冒险的避免

    上一篇已经介绍了流水线的相关和冒险,本篇介绍避免流水线冒险几种技术. 暂停技术(Stalling)避免数据冒险 ---- 通过上一篇的介绍,PIPELINE的数据冒险只发生在读/取同一个程序寄存器的时 ...

最新文章

  1. Poj2420 A Star not a Tree? 模拟退火算法
  2. Linux系统调用及用户编程接口(API)学习
  3. C# 删除指定目录下具有某后缀的全部文件
  4. MATLAB机器学习系列-5 RBF、GRNN和PNN神经网络原理及其例子代码
  5. HDU.5909.Tree Cutting(树形DP FWT/点分治)
  6. 记一个简单的保护if 的sh脚本
  7. [Deep Learning]任意层cnn的matlab版本实现
  8. 首个开源 Linux 系统登陆火星,占有率超 Windows,一同登录还有一款安卓手机芯片...
  9. DDD~DDD从零起步架构说明
  10. 浅入浅出 MySQL 索引
  11. 微软发布 .Net Core 3.0 版重大更新,对开发者来说意味着什么?
  12. Java安装以及环境配置
  13. 读取jar包中的资源文件
  14. Atitit 信息链(Information Chain)的概念理解 attilax总结
  15. RocketMQ源码解析:Message存储
  16. griddata三维空间插值
  17. 多电压等级计算机潮流计算,电力系统稳态分析教学心得
  18. ES3之cookie
  19. FusionGAN:一种生成式红外与可见光图像融合对抗网络
  20. 3w最简单led灯电路图_一款简单实用的LED灯驱动电路

热门文章

  1. 以自己的电脑作为服务器,搭建网站,外网可访问
  2. 商务网站建设与维护【3】
  3. java 设置纸张大小设置_java 用itext设置pdf纸张大小操作
  4. 【C语言进阶】字符函数和字符串函数
  5. C++刷题笔记(4)——leetcode209、904
  6. 8.4 内存映射文件
  7. 火车头采集器文章翻译插件(文章标题内容中英双语对照|自动插入相关图片)
  8. 爆破的思路和断点的设置
  9. 安卓技术实战01 第一个安卓APP案例
  10. STL——vector与迭代器