computer organization and design——RISC-V——chapter4-4

 An Overview of Pipelining:

pipelining——An implementation technique in which multiple instructions are overlapped in execution, much like an assembly line.

Today, pipelining is nearly universal.

本节主要依靠一个类比来概述流水线术语和问题。如果你只对全局感兴趣,你应该专注于这一部分,然后跳到第4.10和4.11节,看看在英特尔酷睿i7和ARM Cortex-A53等最新处理器中使用的先进流水线技术的介绍。如果您对探索流水线计算机的结构感兴趣,本节是对第4.6节到第4.9节的一个很好的介绍。任何洗过很多衣服的人都会直觉地使用流水线。非流水线洗衣方式如下:

1. 把脏衣服放进洗衣机里。
2. 洗衣机洗完后,把湿的东西放在烘干机里。
3. 烘干机用完后,把干的东西放在桌子上折叠起来。
4. 折叠好后,把衣服收起来。

做完后,从下一个脏东西开始。

流水线方法花费的时间要少得多。一旦 洗衣机完成第一次装载并放入烘干机(开始第二个阶段),就load the washer with the second dirty load. 

The pipelining paradox :

工作流程is not shorter for pipelining,更快的原因是,所有的东西都是并行工作的,所以每小时完成的负载更多。

(流水线减少完成一次洗衣的时间,是提高了我们洗衣系统的吞吐量。)

(当我们有很多衣服要做时,吞吐量的提高会减少完成工作的总时间。)

(流水线版本中,在工作负载的开始和结束时,流水线并没有完全满;当任务数量与流水线中的阶段数量相比很大时,此启动和结束不会影响性能。如果负载的数量远远大于4,那么阶段将在大部分时间都是满的,吞吐量的增加将非常接近4。

同样的原则也适用于我们流水线的处理器指令执行。

RISC-V指令通常采取五个步骤:

1、从内存中获取指令。

2、读取寄存器并解码指令。

3、执行操作或计算地址。

4、访问数据内存中的操作数(如果需要)。

5、将结果写入寄存器(如有必要)。

因此,我们在本章中探讨的RISC-V管道有五个阶段。下面的示例表明,流水线加快了指令的执行速度,就像它加快了洗衣机的速度一样。

Single-Cycle versus Pipelined Performance

例子:

为了使这个讨论具体化,让我们创建一个管道。在本例和本章的其余部分中,我们将注意力限制在七条指令上:加载双字(ld)、存储双字(sd)、加(add)、减(sub)和(and)、或(OR)和分支(beq)。

将所有指令都采用一个时钟周期的单周期实现的指令之间的平均时间与流水线实现的平均时间进行比较。

假设本例中的主要功能单元的操作时间是:指令或数据的内存访问为200ps,ALU操作为200ps,寄存器文件读写为100ps。在单周期模型中,每条指令只占用一个时钟周期,因此时钟周期必须延长以适应最慢的指令。

单周期设计必须考虑到图4.24中最慢的指令—它是ld,因此每条指令所需的时间为800 ps。

图4.25比较了三条加载寄存器指令的非流水线和流水线执行。

在非流水线设计中,第一个和第四个指令之间的时间是3×800 ps或2400 ps

pipelined execution clock cycle must have the worst-case clock cycle of 200 ps
 

两者都使用相同的硬件组件,其时间

如图4.24所示。在这种情况下,我们可以看到平均指令间隔时间的加速,从800 ps到200 ps。

将此图与图4.23进行比较。对于洗衣房,我们假设所有阶段都是平等的。如果烘干机是最慢的,那么烘干机阶段将设置阶段时间。计算机的流水线阶段时间也受到最慢资源的限制,无论是ALU操作还是内存访问。

假设:We assume the write to the register file occurs in the first half of the clock cycle and the read from the register
file occurs in the second half. We use this assumption throughout this chapter.

所有流水线级都采用一个时钟周期,因此时钟周期必须足够长,以适应最慢的操作。正如单周期设计必须采用800ps的最坏情况时钟周期一样,即使有些指令的速度可以达到500ps,流水线执行时钟周期也必须采用200ps的最坏情况时钟周期,即使有些阶段只需要100ps。

我们可以把上面关于流水线加速的讨论变成公式,如果阶段完全平衡,那么流水线处理器上的指令之间的时间(假设理想条件)等于:

在理想条件下,使用大量指令时, the speed-up from pipelining is approximately equal to the number of pipe stages; a five-stage pipeline is nearly five times faster.然而,这个例子表明,这些阶段可能是不完全平衡的。此外,流水线涉及一些开销,其来源很快就会更清楚。因此,流水线处理器中每条指令的时间将超过可能的最小值,并且速度将小于流水线级的数量

流水线指令集的设计:

即使有了对流水线的简单解释,我们也可以深入了解RISC-V指令集的设计,该指令集是为流水线执行而设计的。

首先,所有RISC-V指令的长度都是相同的。这种限制使得在第一个流水线阶段获取指令和在第二个阶段解码它们变得更加容易。在像x86这样的指令集中,指令从1字节到15字节不等,流水线是相当困难的。x86体系结构的现代实现实际上将x86指令转换为看起来像RISC-V指令的简单操作,然后将简单操作而不是本机x86指令流水线传输!

其次,RISC-V只有一些指令格式,其中 源寄存器和目标寄存器字段位于每条指令中的同一位置。

第三,内存操作数只出现在RISCV的加载或存储中(loads or stores)。这个限制意味着我们可以使用execute阶段计算内存地址,然后在下一阶段访问内存。

如果我们可以像x86那样对内存中的操作数进行操作,stages 3 and 4 would expand to an address stage, memory stage, and then execute stage. We will shortly see the downside of longer pipelines.

Pipeline Hazards

There are situations in pipelining when the next instruction cannot execute in the following clock cycle. These events are called hazards, and there are three different types.

Structural Hazard:When a planned instruction cannot execute in the proper clock cycle because the hardware does not support the combination of instructions that are set to execute

如果我们使用洗衣机和烘干机的组合而不是单独的洗衣机和烘干机,或者如果我们的室友正忙着做其他的事情而不把衣服收起来,洗衣房就会出现结构性危险。

如果图4.25中的管道有第四条指令,我们可以在同一个时钟中看到,the first instruction is accessing data from memory while the fourth instruction is fetching an instruction from that same memory. Without two memories, our pipeline could have a structural hazard

data hazard:当计划的指令由于执行指令所需的数据还不可用  而 不能在正确的时钟周期内执行时。在计算机管道中,数据危险源于一条指令对一条仍在管道中的前一条指令的依赖

 

例如,

假设我们有一个加法指令后跟一个使用该和(x19)的减法指令:

add x19, x0, x1
sub x2, x19, x3

如果不进行干预,数据危险可能会严重阻碍管道。add指令直到第五阶段才写入结果,这意味着我们将不得不在流水线中浪费三个时钟周期。

 

尽管我们可以依靠编译器来删除所有这些危险,但这些依赖关系发生得太频繁,最终无法删除的还是有延迟时间太长,无法指望编译器将我们从这个困境中解救出来。

对于上面的代码序列,只要ALU创建加法的和,我们就可以将其作为减法的输入。添加额外的硬件以提前从内部资源中检索丢失的项称为转发或绕过

EX:

在这里,我们使用符号来表示物理资源,并在本章中使用管道阶段的缩写。

(Graphical representation of the instruction pipeline, similar in spirit to the laundry pipeline in Figure 4.23.)

五个阶段的符号:

IF表示指令获取阶段,框表示指令内存;output program mem

ID表示指令解码/“寄存器文件读取”阶段的,图形显示正在读取的寄存器堆.output reg file

EX表示执行阶段,图形表示ALU;

MEM用于内存访问阶段,框表示数据内存;

WB用于写回阶段,图形显示正在写入的寄存器堆。input reg file

阴影表示该元素被指令使用。

因此,MEM的背景是白色的,因为add不访问数据内存。

寄存器文件或内存右半部分的阴影表示在该阶段读取元素,而左半部分的阴影表示在该阶段写入元素。因此,在第二阶段,ID的右半部分被着色,因为寄存器文件被读取;在第五阶段,WB的左半部分被着色,因为寄存器堆是写的。

解答:FIGURE 4.27 Graphical representation of forwarding.

 

 

 

FORWARDING 工作非常出色,在第4.7节中有详细说明。但是,它不能阻止所有的管道阻塞。

(关注:前指令在哪个阶段才可以得到数据,后指令在哪个阶段就需要输入数据?

算术运算类:在EX前需要用,在EX后得到

LOAD:在EX前需要用地址,在MEM后得到正确的寄存器值

STORE:在EX前需要用?(看下面一个例子的意思),在MEM后MEM中相应地址有存储了合逻辑的值)

例如,假设第一条指令是load x1而不是add。从图4.27可以"想象",sub所需的数据在第一条指令的第四阶段之后才可用,这对于sub的第三阶段的输入来说太晚了。因此,即使使用forwading,也必须暂停一个阶段,如图4.28所示。此图显示了一个重要的管道概念——a pipeline stall, but often given the nickname bubble.

第4.7节展示了我们如何处理这样的情况,使用“硬件检测"和"stall",或者"重新排序代码以避免加载使用管道stall"的软件,如本例所示。

load-use data hazard A specific form of data hazard in which the data being loaded by a load instruction have not yet become available when they are needed by another instruction.)

pipeline stall:Also called bubble. A stall initiated in order to resolve a hazard.
 

例子重新排序代码以避免加载使用管道stall:

例子

考虑C中的以下代码段:

a=b+e;

c=b+f;

这是为这个段生成的RISC-V代码,假设变量在内存中,可作为x31的偏移量寻址:

ld x1,0(x31)//加载b

ld x2,8(x31)//加载e

add x3,x1,x2//b+e

sd x3,24(x31)//存储

ld x4,16(x31)//加载f

add x5,x1,x4//b+f

sd x5,32(x31)//Store c

找出前面代码段中的危险并重新排序避免管道堵塞的说明。

回答:

两个加法指令都有危险,因为它们各自依赖于先前的ld指令。

使用 "forwading"消除一些别的潜在hazards,  包括第一条add指令对第一个ld指令的依赖,and any hazards for store
instructions.

向上移动第三个ld指令以成为第三个指令可消除以下两种危险:

ld x1, 0(x31)
ld x2, 8(x31)
ld x4, 16(x31)
add x3, x1, x2
sd x3, 24(x31)
add x5, x1, x4
sd x5, 32(x31)

图4.8

when an R-format instruction following a load tries to use the data.,即使是转发,我们也需要一个暂停,没有这个暂停,从内存访问阶段输出到执行阶段输入的路径将在时间上后退,这是不可能的。

这个图实际上是被简化了,因为我们要等到提取并解码减法指令之后才能知道是否需要暂停。

Control Hazards:是由于在执行其他指令时需要根据一条指令的结果作出决定

也称为branch hazard。当正确的指令无法在正确的管道时钟周期中执行时,因为所获取的指令不是所需的指令;

计算机中的等效决策任务是分支指令。注意,我们必须开始获取在下一个时钟周期中跟随分支的指令。

然而,管道不可能知道下一条指令应该是什么,因为它只是从内存中接收到分支指令!与洗衣房一样,一种可能的解决方案是在取分支之后立即暂停,等待管道确定分支的结果并知道要取哪个指令地址。

假设我们放入了足够多的额外硬件,这样就可以在管道的第二阶段测试寄存器、计算分支地址和更新PC(详细信息请参见第4.8节)。(so that we can test a register, calculate the branch address, and update the PC during the second stage of the pipeline (see Section 4.8 for details).
 

即使增加了硬件,

涉及条件分支的管道如图4.29所示。如果分支出现故障,则要执行的指令在启动前被暂停一个额外的200ps时钟周期



branch指令带来的stall对CPI的影响,branch指令占总指令的百分比越大,CPI就越大。

第二种解决方案:

如果我们无法在分支指令的第二个阶段作出判断( as is often thecase for longer pipelines),我们将会看到更大的slowdown ,这样的代价太大了,所以更多的计算机会使用——”预测“
如果你是对的,它不会减慢管道的速度,When you are wrong, however, you need to redo the load that was washed while guessing the decision。

预测:比如总是假设分支不会被taken, When you’re right, the pipeline proceeds at full speed.

Only when conditional branches are taken does the pipeline stall. Figure 4.30 shows such an example.

4.30:

更复杂的分支预测版本:In the case of programming, at the bottom of loops are conditional branches that branch back to the top of the loop. Since they are likely to be taken and they branch backward, we could always predict taken for conditional branches that branch to an earlier address.(在LOOP里,总把branch放在LOOP最后,总是预测branch被taken.)

动态硬件预测器:这种僵化的分支预测方法依赖于刻板的行为,而不考虑特定分支指令的个性。与之形成鲜明对比的是,动态硬件预测器根据每个条件分支的行为进行猜测,并可能在程序生命周期内更改条件分支的预测。根据我们的类比,在动态预测中,人们会看制服有多脏,然后猜测公式,根据最近猜测的成功率调整下一个预测。

一种流行的条件动态预测方法:根据条件分支的历史记录,使用最近的过去行为来预测未来。其结果是动态分支预测器能够以90%以上的准确率正确地预测条件分支(见第4.8节)。当猜测错误时,管道控件必须确保错误猜测的条件分支后面的指令无效,并且必须重新启动来自正确分支地址的管道。在我们的洗衣房里类似地,我们必须停止使用新的负载,这样我们才能重新启动错误预测的负载。与所有其他控制危险的解决方案一样,较长的管道会加剧问题,在这种情况下会增加预测失误的成本。第4.8节更详细地描述了控制危险的解决方案。

a third approach to the control hazard——delayed decision:

延迟的分支总是执行下一个顺序指令,并且在该指令延迟之后发生分支。它对MIPS汇编语言程序员是隐藏的,因为汇编程序可以自动排列指令以获得程序员所需的分支行为。MIPS软件将在延迟的分支指令之后立即放置一条指令。Since delayed branches are useful when the branches are short, it is rare to see a processor with a delayed branch of more than one cycle. For longer branch delays, hardware-based branch prediction is usually used.

Pipeline Overview Summary:

它有一个实质性的优势,不像对多处理器编程(见第6章),它对程序员来说是根本不可见的。

 

在本章接下来的几节中,我们将介绍使用第4.4节中单周期实现的RISC-V指令子集的流水线的概念,并展示其流水线的简化版本。然后,我们将讨论流水线引入的问题以及在典型情况下可以达到的性能。

第4.10节介绍了先进的流水线概念,如超标量和动态调度,如果您希望更多地关注软件和流水线的性能影响,现在您有足够的背景知识可以跳到第4.10节

第4.8节了解有关分支危险解决方案的更多信息

第4.9节中了解如何处理异常

第4.7节中FORWARDING和stall的实现

在内存系统之外,流水线的有效运行通常是决定处理器的CPI及其性能的最重要因素。

 

正如我们将在第4.10节中看到的,理解现代多问题流水线处理器的性能是复杂的,需要理解的不仅仅是简单流水线处理器中出现的问题。

尽管如此,结构、数据和控制冲突仍然存在.在简单的管道和更复杂的管道中都很重要。

对于现代管道,结构冲突通常围绕浮点单元旋转,浮点单元可能没有完全流水线,

控制冲突通常更多地是integer programs,中的问题(往往具有较高的条件分支频率和较低的可预测分支)

数据冲突可能是整数和浮点程序的性能瓶颈。通常,在浮点程序中处理数据危险比较容易,因为较低的条件分支频率和较规则的内存访问模式允许编译器尝试调度指令以避免危险。在具有较少的常规内存访问、涉及更多指针使用的整数程序中执行此类优化更为困难。正如我们将在第4.10节中看到的,有更多雄心勃勃的编译器和硬件技术可以通过调度减少数据依赖性。

流水线不会减少完成单个指令(也称为延迟)所需的时间。

例如,五级流水线仍然需要五个时钟周期才能完成指令。

在第1章中使用的术语中,流水线提高了指令吞吐量,而不是单个指令的执行时间或延迟

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值