数字电路设计——流水线处理器

news2024/11/23 13:23:00

数字电路设计——流水线处理器

从内存或是寄存器组读写、操作ALU是处理器中最耗时的操作。我们将一个指令拆成五个流水线阶段,每个阶段同时执行耗时的组合逻辑。这五个阶段分别是取指令、解码、执行、访存和写回。

在取指令阶段,处理器从指令存储器中读取一条指令。在解码阶段,处理器从寄存器组读取两个操作数,并解码指令产生相应的控制信号。在执行阶段,处理器执行ALU命令。在访存阶段,处理器从内存中读取数据或者是写入数据。最后,在写回阶段,处理器将结果写回到寄存器组。

下图是单周期和流水线CPU的执行时序比较:

单周期和流水线比较
下图是一些指令的执行过程:

执行过程
其中IM表示instruction memory,RF表示register file,DM表示data memory。阴影的器件表示该器件在本周期使用,特别的,RF的左边阴影表示写RF,右边阴影表示读RF。

相对于单周期和多周期的CPU设计,流水线CPU最大的困难就是如何处理Hazards(冒险)问题,Hazards发生于一个指令的执行过程依赖于之前的几个指令,这就导致所依赖的指令没有执行完成就开始执行了下一条指令,这将会导致不正确的结果。因此,除了介绍流水线CPU的数据通路设计,我们还需要介绍解决Hazards的几个常用方案,包括forwarding(前送)、stalls(等待)、flushes(清空)来解决Hazards问题。

流水线数据通路

流水线数据通路的设计思想很简单,在原有的单周期的CPU的基础上,人为的将数据通路切分成5个阶段,每个阶段使用FF触发器隔开即可:

流水线数据通路
上图中一个寄存器组的CLK接入了一个非门,这样则是在一个周期的下降沿写入数据,可以实现在一个周期的前半部分读取数据,在一个周期的后半部分写入数据。

上图中一个不易发现但最为严重的问题是,寄存器组的写入地址A3,当写回阶段将数据写回寄存器的时候,WD3的输入数据是正确的,但是A3写入地址则是后几个指令的写入地址,解决这个问题可以同步A3的数据传输:

改正A3
除此之外,PC计数器的下一个PC值PCF’也有类似的问题,假如当前指令需要修改PC计数器的值,只能在写回阶段修改,但是执行到写回阶段,当前指令的后几条指令已经开始执行了,这些反馈回路都会造成Hazards,之后我们会修正这种控制Hazards。

流水线控制

流水线控制逻辑和单周期的CPU使用同样的逻辑控制单元,不同的是,一个指令的控制信号同样需要进行流水同步,这样保证在每个阶段收到的控制信号是当前指令的控制信号,而不是下一条指令的控制信号:

流水线控制

Hazards

流水线CPU中的指令存在多个指令同时执行的情况,因此当一个指令依赖于上几条未执行结束指令的结果的时候,此时就会发生Hazards。下图展示了一种Hazards的情况:

Hazards

图中指令二和三都需要指令一add的s8寄存器的结果,而指令四是在第5周期的后半周期读,所以能够读取到正确的结果。

图中的Hazards又被称为写后读(RAW,read after write)Hazard 。若不进行干预,则会产生不正确的结果。最简单的解决方案是从软件汇编的角度来解决,人为的在第一条指令后面插入两个nop指令,这称为软件互锁(software interlock):

在这里插入图片描述
这样就能够保证后面的指令都是正确的结果,但是这种方法既拖慢了流水线的速度,也增加了编译器的实现难度。

若仔细观察,第一条指令的结果在周期3就可以得出,因此剩余的指令可以直接使用周期三的结果而不用等待写入寄存器组,这称为数据前送。但是特殊情况下我们还是需要等待指令结果的执行完毕,称为Stalls。

总体来说Hazards分为数据Hazards和控制Hazards,数据Hazards就如例子所示,而控制Hazards则是发生在需要修改PC寄存器的时候,在修改PC寄存器的指令结束运行之前,可能已经在执行接下来下面的指令了,而正确的执行过程则是执行跳转处的指令,这将导致指令的意外执行。

通过数据前送解决Hazards

一些Hazards能够被数据前送(forwarding)也称旁路(bypassing)解决,有些指令需要等到访存或是写回阶段才能执行完毕,其中结果早在ALU阶段就已经计算得出,因此可以将ALU阶段执行的结果直接送入下一个指令流水,完成数据前送。

我们可以在ALU部件的两个操作数的多路选择器中增加来自访存和写回阶段的总线,如图:

数据前送

下图是实现电路,在原有的基础上增加了Hazard 单元组件,以及ALU前端的两个前送多路选择器,Hazard 单元组件接收当前ALU执行阶段的两个操作数,以及当前要写入的寄存器地址RdM和RdW,来决定是否从访存或是写回阶段前送数据到ALU中:

冒险控制

当前Hazard 单元组件还要接收RegWriteW和RegWriteM信号来确定寄存器是否被真的写入了。因此,数据前送发生在,当前周期下,写回或访存阶段要写入寄存器A,并且当前ALU要从寄存器A读取值。有一个例外,X0被硬连线为0,不应该被前送。

若写回和访存都匹配当前ALU的操作数的话,访存有更高的优先级,因为其代表了最近一条的指令。下面给出的ForwardAE的逻辑,ForwardBE的逻辑也同理:

前送组合逻辑

通过Stalls解决Hazards

数据前送能解决当一个ALU执行阶段的RAW。不幸的是,lw指令不行,lw指令必须等待指令访存之后才能得到结果,这样lw指令就无法再执行阶段进行数据前送。下面的图片说明了这个问题:

lw指令的问题
我们称lw是一个两周期延迟的指令,因为lw指令的结果最少在其之后的第二个周期(or指令)才有效,这种无法通过数据前送来解决。

解决方案就是Stalls(等待)。将一个指令挂起,直到源操作数可用。下图展示了and指令在译码阶段被挂起:

挂起
译码阶段被挂起了一个周期,当然在译码之前的阶段(取指令)也需要挂起一个周期。在第5周期,or在后半周期读,而lw在前半周期写,因此不需要数据前送。

注意在第4周期执行阶段没有用到,第5周期访存阶段没有用到,第6周期写回阶段没有用到。这种一个周期暂停使用的现象就像气泡一样往前传递。气泡最后会在5个周期内被清除,因此气泡的存在只有极小的性能影响。

总之,Stall一个阶段可以通过停用上一个阶段的FF触发寄存器来实现,因此本阶段的输入不会发生变化,当一个阶段被Stall之前,之前的阶段都应该被Stall,并且该阶段之后的阶段应该被清空(flushed),来防止指令被重复执行。所以,Stall对性能有较大的影响,因此只在必要的阶段使用。

下图展示了增加Stalls功能的Hazard 处理单元:

Stalls功能
当下面条件满足的时候,启动Stall:

  1. 在执行阶段需要从内存加载一个字(ResultSrcE0 = 1)
  2. 内存加载要写入的寄存器RdE与当前周期译码阶段下面的Rs1D或Rs2D匹配。

当Stall发生的时候,StallD和StallF会阻止一个周期的取指令和译码,FlushE同样清空一个执行阶段ALU的输入,这样可以实习向前传播一个周期的空运行(nop) ,即引入一个气泡。

我们将启用Stall的信号记为lwStall,那么:

Stall启动逻辑

解决控制Hazards

beq指令存在一个控制Hazards,因为只有beq在更新PC之后,CPU才能决定下一个指令的位置。

一种解决办法的为下面的指令添加两个周期的Stalls,beq在执行阶段之后才知道beq的结果,但是这会严重影响性能。

另一种方法称为分支预测,CPU可以先继续往下执行,一旦发生指令跳转,CPU可以立刻丢弃错误执行的指令,若发送预测错误,浪费的两个周期称为分支预测失败罚时。

分支预测

上图中beq指令在周期3才能决定下一个指令是0x24还是0x58,假如CPU预测不进行分支跳转,则CPU载入下面两个指令的代码进行执行,当发生指令跳转之后,CPU必须清空(flushed)前两个周期IM和RF的代码,在第4个周期开始执行0x58的代码。

分支预测功能
上图是实现清除前两个流水线的功能,当Hazard 单元判断PCSrcE为1 的时候,表明发生分支跳转,因此FlushD,FlushE被置1,取指令阶段和译码阶段的FF除法寄存器被同步清空,执行逻辑如下:

执行逻辑

性能分析

理想情况下流水线处理器的CPI为1,因为一个周期就会取指令一次。但是因为Stalls的存在,必然会浪费几个周期,因此CPI应稍微大于1,取决于具体执行的代码。

具体的当一个需要Stall的load指令需要的CPI=2,当一个分支预测失败的beq指令需要CPI=3,其他情况指令的CPI=1。

通过关键路径来决定最短时钟周期:

最短路径

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/748208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python -m 是什么命令

python -m 命令是什么意思 首先python --help 可以看到-m的含义:意思是将库中的python模块用作脚本去运行。 python --help 命令显示结果 python -m xxx.py 和python xxx.py 有什么区别 这是两种加载py文件的方式: 叫做直接运行(python xxx.py&#xf…

Android 音频可视化:频谱特效的探索与实践

音频可视化,一言以蔽之,就是声音到图像的转换。 随着视觉工业时代的到来,用户逐渐重视产品的极致体验,在市场上诸多优秀的音乐类APP中,频谱动效 是一个经典的应用场景: 图片来源:咪咕音乐 本文…

【C++】C++的IO流

目录 一、C语言的输入与输出 二、流的概念 三、CIO流 1、C标准IO流 2、C文件IO流 四、stringstream的简单介绍 一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量…

项目管理:如何减少项目中的信息差

在项目管理中,信息差的存在是难以避免的。 一方面,由于项目干系人各自的角色不同,项目经理不可能让每个人都知道所有的事情,以免在信息的海洋中产生更多的干扰。 另一方面,项目干系人需要了解项目的情况&#xff0c…

华为OD机试真题 Java 实现【数字序列比大小】【2023 B卷 100分】,田忌赛马,永远比你大,你服不服?

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 大家好,我是哪吒。 做技术,我是认真的,立志于打造最权威的华为OD机试真题专栏,帮助那些与我有同样需求的人&#xff…

ES6——Promise

promise 含义:异步编程解决方案 特点:1、状态不受外界影响,状态有三种:pending、fulfilled、rejected 2、状态不可逆,只能pending -> fulfilled、pending -> rejected 缺点:无法取消、不设置回调函…

常见的人体静电消除器的工作原理

人体静电消除器是一种用于消除人体带有静电的装置。静电是指物体表面具有电荷的现象,当人体带有静电时,会导致一些不舒适的感觉,同时也容易引起电击事故。 人体静电消除器的工作原理主要通过以下几个方面来实现: 1.接地&#xf…

深入篇【Linux】学习必备:认识冯诺依曼系统+理解操作系统(‘‘管理‘‘)

深入篇【Linux】学习必备:认识冯诺依曼系统理解操作系统(管理) Ⅰ.冯诺依曼系统结构1.特点(what)2.理解(why)3.案例(how) Ⅱ.操作系统概念与定位1.概念(what)2.设计OS目的(why)3.管理(how) Ⅰ.冯诺依曼系统结构 1.特点(what) 我们认识的计算机&#xff…

ETHERCAT转ETHERCAT网关三菱plc支持ethercat吗

大家好,今天要和大家分享一款神器——远创智控YC-ECAT-ECAT通讯网关!这款网关有什么厉害的呢?且听我慢慢道来。 首先,YC-ECAT-ECAT是一款自主研发的ETHERCAT从站功能的通讯网关。那什么是ETHERCAT呢?简单来说&#xff…

揭秘ChatGPT的流式返回

107. 揭秘ChatGPT的流式返回 ChatGPT是一种强大的语言模型,可以生成自然语言响应。在传统的请求/响应模型中,客户端发送请求,服务器处理请求后返回响应。但是,使用流式返回可以实现持续的数据流,使得客户端能够实时接…

水文水动力模型在城市内涝、城市排水、海绵城市规划设计中深度应用

随着计算机的广泛应用和各类模型软件的发展,将排水系统模型作为城市洪灾评价与防治的技术手段已经成为防洪防灾的重要技术途径。将聚焦于综合利用GIS及CAD等工具高效地进行大规模城市排水系统水力模型的建立,利用SWMM实现排水系统水力模拟。讲解SWMM深度…

rabbitmq使用springboot实现fanout模式

一、fanout模式 类型&#xff1a;fanout特点&#xff1a;Fanout—发布与订阅模式&#xff0c;是一种广播机制&#xff0c;它是没有路由key的模式。 二、实现 1、引入相应的pom文件 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project x…

左神算法 重要技巧:递归的加速技巧(斐波那契数列套路)以及推广

目录 【案例1】【十分重要 &#xff1a; 斐波那契递归套路&#xff0c;只要像斐波那契这种严格递归都可以进行类似的优化】 【有严格的递归项后&#xff0c;通过线性代数的知识进行优化】 【代码实现】 【技巧推广】 【实例1 使用这个技巧】 【题目描述】 【思路解析】 …

求两个数的最大值max

函数实现 int max(int a, int b); 函数接收两个整数参数&#xff0c;在内部用if语句判断哪个大&#xff0c;返回大的即可。 完整代码 #include <iostream> using namespace std;int max(int a, int b) {if (a > b){return a;}else{return b;} }int main() {int n1…

开发工具篇第25讲:阿里云MFA绑定Chrome浏览器Authenticator插件

开发工具篇第25讲&#xff1a;阿里云MFA绑定Chrome浏览器Authenticator插件 本文是开发工具篇第25讲&#xff0c;登录阿里云旗下产品时&#xff0c;需要使用mfa登录&#xff0c;每次如果要用手机看mfa码很麻烦&#xff0c; Chrome浏览器提供了一个快捷的登录方法&#xff0c;可…

软件工程师,学习下JavaScript ES6新特性吧

概述 作为一名软件工程师&#xff0c;不管你是不是前端开发的岗位&#xff0c;工作中或多或少都会用到一点JavaScript。JavaScript是大家所了解的语言名称&#xff0c;但是这个语言名称是Oracle公司注册的商标。JavaScript的正式名称是ECMAScript。1996年11月&#xff0c;JavaS…

Mysql根据积分排名

积分表&#xff1a;t_participant_points 1、带并列 SELECT p.*, CASE WHEN prevRank p.total_points THEN curRank WHEN prevRank : p.total_points THEN curRank : curRank 1 END AS ranking FROM ( SELECT total_points …

LabVIEW-实现波形发生器

一、题目 用两种方法实现一种多类型信号波形发生器&#xff08;至少包括&#xff1a;正弦波、三角波、方波等&#xff09;&#xff0c;可以调节信号频率、幅度、相位等参数&#xff0c;可以图形化显示信号波形。 需要给出产生信号波形的基本方法、程序设计基本方法以及程序实现…

931.下降路径最小和

931.下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列&#xff08;即…

【图像处理】经营您的第一个U-Net以进行图像分割

一、说明 AI厨师们&#xff0c;今天您将学习如何准备计算机视觉中最重要的食谱之一&#xff1a;U-Net。本文将叙述&#xff1a;1语义与实例分割&#xff0c;2 图像分割中还使用了其他损失&#xff0c;例如Jaccard损失&#xff0c;焦点损失&#xff1b;3 如果2D图像分割对您来说…