1、第四章 指令级并行Instruction-Level Parallelism, ILP,指令之间存在的潜在并行性称为指令级并行(Instruction-Level parallelism, ILP)思考:是什么阻碍实现指令级并行? CPI流水线 = CPI理想 ?,第四章 指令集并行 指令的相关,第四章 指令集并行 指令的相关,程序中指令之间的依赖关系,描述了指令和指令之间的属性数据相关:指令 i 以后的指令使用 i 产生的结果名相关:指令使用的寄存器或者存储器称为名反相关 : 指令 j 写的名是 指令 i 读的名输出相关:指令 j 写的名是 指令 i 写的名控制相关 流水线控制冲突(相关),
2、第四章 指令级并行指令的相关与流水线相关(冲突),指令的相关是程序的固有属性;流水线的冲突(相关)是由于指令的相关属性导致的。对应关系:数据相关 流水线写后读冲突(相关)名相关反相关 流水线写后写冲突(相关)输出相关 流水线读后写冲突(相关)控制相关 流水线控制冲突(相关),第四章 指令集并行,流水线实际CPI理想流水线的CPI加上各类停顿的时钟周期数: CPI流水线 = CPI理想 + 停顿结构冲突 + 停顿数据冲突+ 停顿控制冲突理想CPI是衡量流水线最高性能的一个指标。IPC:Instructions Per Cycle (每个时钟周期完成的指令条数),第四章 指令级并行,本章所研究的技
3、术,第四章 指令级并行循环级并行性,基本程序块基本程序块:一段除了入口和出口以外不包含其他分支的线性代码段。程序平均每57条指令就会有一个分支。,第四章 指令级并行循环级并行性,基本程序块基本程序块:一段除了入口和出口以外不包含其他分支的线性代码段。程序平均每57条指令就会有一个分支。,第四章 指令级并行循环级并行,循环级并行:使一个循环中的不同循环体并行执行。开发循环体中存在的并行性最常见、最基本是指令级并行研究的重点之一例如,考虑下述语句: for (i=1; i=500; i=i1) ai=ais;每一次循环都可以与其他的循环重叠并行执行;在每一次循环的内部,却没有任何的并行性。,本节中
4、,我们使用的浮点流水线延迟为:,第四章 指令级并行循环展开调度基本方法,假设指令i在前,指令j在后;所谓的“延迟”,是由于发生冲突造成的停顿时间。(采用定向技术,没有结构冲突),例4.6 对于下面的源代码,转换成MIPS汇编语言,在不进行指令调度和进行指令调度两种情况下,分析其代码一次循环所需的执行时间。 for (i=1; i=1000; i+) xi = xi + s;,第四章 指令级并行循环展开调度基本方法 - 实例,把该程序翻译成MIPS汇编语言代码:Loop:L.D F0,0(R1) / 取一个向量元素放入F0 ADD.D F4,F0,F2 / 加上在F2中的标量 S.D F4, 0
5、(R1)/ 保存结果 DADDIU R1,R1,#-8/指针减8(每个数据占8个字节) BNE R1,R2,Loop / 如果R1不等于R2,未结束,继续其中:整数寄存器 R1:指向向量中的当前元素,初值为向量中最高端元素的地址)整数寄存器 R2:8(R2)指向最后一个元素。浮点寄存器 F2:用于保存常数 s。,第四章 指令级并行循环展开调度基本方法 - 实例,不进行指令调度的情况下,程序的实际执行情况:,指令流出时钟 Loop: L.D F0,0(R1) 1 (空转) 2 ADD.D F4,F0,F2 3 (空转) 4 (空转) 5 S.D F4, 0(R1) 6 DADDIU R1,R1,
6、# -8 7 (空转) 8 BNE R1,R2,Loop 9 (空转) 10 每个元素的操作需要10个时钟周期,其中5个是空转周期。,第四章 指令级并行循环展开调度基本方法 - 实例,指令调度以后,程序的执行情况如下:把DADDIU指令调度到了L.D指令和ADD.D指令之间的“空转”拍。把S.D指令放到了分支指令的延迟槽中。对存储器地址偏移量进行调整。,第四章 指令级并行循环展开调度基本方法 - 实例,Loop: L.D F0,0(R1) (空转) ADD.D F4,F0,F2 (空转) (空转) S.D F4, 0(R1) DADDIU R1,R1,#-8 (空转) BNE R1,R2,Lo
7、op (空转),Loop: L.D F0, 0(R1) DADDIU R1,R1,#-8 ADD.D F4, F0, F2 (空转) BNE R1,R2,Loop S.D F4,8(R1),第四章 指令级并行循环展开调度基本方法 - 实例,指令流出时钟Loop: L.D F0, 0(R1) 1 DADDIU R1, R1, #-8 2 ADD.D F4, F0, F2 3 (空转) 4 BNE R1, Loop 5 S.D F4,8(R1) 6 一个元素的操作时间从10个时钟周期减少到6个,其中5个周期是有指令执行的,1个为空转周期。,第四章 指令级并行循环展开调度基本方法 - 实例,问题只有
8、L.D、ADD.D和S.D这3条指令是有效操作。 (取、加、存)占用3个时钟周期。而DADDIU、空转和BEN这3个时钟周期都是附加的循环控制开销。如何改进?,第四章 指令级并行循环展开调度基本方法 - 实例,循环展开技术把循环体的代码复制多次并按顺序排列,然后相应调整循环的结束条件。这给编译器进行指令调度带来了更大的空间。,第四章 指令级并行循环展开调度基本方法 - 实例,第四章 指令级并行循环展开调度基本方法,基本思想:把循环展开后,通过重命名和指令调度来开发更多的并行性。调度: 通过改变指令在程序中的位置,将相关指令之间的距离加大到不小于指令执行延迟的周期数,这样就可以将相关的指令转化为
9、无关指令。编译器完成这种指令调度的能力受限于两个特性:程序固有的指令级并行性;流水线功能部件的执行延迟。,循环展开和指令调度时要注意以下几个方面:保证正确性。 在循环展开和调度过程中尤其要注意两个地方的正确性:循环控制,操作数偏移量的修改。注意有效性。 只有能够找到不同循环体之间的无关性,才能有效地使用循环展开。使用不同的寄存器(否则可能导致新的冲突),第四章 指令级并行循环展开调度基本方法 注意事项,删除多余的测试指令和分支指令,并对循环结束代码和新的循环体代码进行相应的修正。注意对存储器数据的相关性分析 例如:对于load指令和store指令,如果它们在不同的循环迭代中访问的存储器地址是不
10、同的,它们就是相互独立的,可以相互对调。注意新的相关性 由于原循环不同次的迭代在展开后都到了同一次循环体中,因此可能带来新的相关性。,第四章 指令级并行循环展开调度基本方法 - 实例,静态调度依靠编译器对代码进行静态调度,以减少相关和冲突。它不是在程序执行的过程中、而是在编译期间进行代码调度和优化。通过把相关的指令拉开距离来减少可能产生的停顿。动态调度在程序的执行过程中,依靠专门硬件对代码进行调度,减少数据相关导致的停顿。,第四章 指令级并行指令的动态调度,优点能够处理一些在编译时情况不明的相关(比如涉及到存储器访问的相关),并简化了编译器;能够使本来是面向某一流水线优化编译的代码在其他的流水
11、线(动态调度)上也能高效地执行。代价 硬件复杂性的显著增加,第四章 指令级并行指令的动态调度,简单流水线的最大的局限性:指令按序流出和执行考虑下面一段代码:DIV.DF4,F0,F2SUB.DF10,F4,F6 ADD.DF12,F6,F14 SUB.D指令与DIV.D指令关于F4相关,导致流水线停顿。ADD.D指令与流水线中的任何指令都没有关系,但也因此受阻。,动态调度的基本思想,第四章 指令级并行指令的动态调度,为了允许乱序执行,我们将5段流水线的译码阶段再分为两个阶段:流出(Issue,IS):指令译码,检查是否存在结构冲突。 (in-order issue)读操作数(Read Oper
12、ands,RO):等待数据冲突消失,然后读操作数。 (out of order execution),第四章 指令级并行指令的动态调度,第四章 指令级并行指令的动态调度,简单的5段流水线中,是不会发生读后写冲突和写后写冲突的。但乱序执行就使得它们可能发生了。例如,考虑下面的代码 DIV.D F10, F0, F2 SUB.D F10, F4, F6 ADD.D F6, F8, F14,存在反相关,存在输出相关,Tomasulo算法可以通过使用寄存器重命名来消除。,动态调度的流水线支持多条指令同时处于执行当中。要求:具有多个功能部件、或者流水功能部件、或者兼而有之。我们假设具有多个功能部件。,第
13、四章 指令级并行指令的动态调度,指令乱序完成带来的最大问题: 异常处理比较复杂 (精确异常处理、不精确异常处理) 动态调度要保持正确的异常行为只有那些在程序严格按程序顺序执行时会发生的异常,才能真正发生。保持正确的异常行为:对于一条会产生异常的指令来说,只有当处理机确切地知道该指令将被执行后,才允许它产生异常。,第四章 指令级并行指令的动态调度,核心思想记录和检测指令相关,操作数一旦就绪就立即执行,把发生RAW冲突的可能性减少到最小;通过寄存器换名来消除WAR冲突和WAW冲突。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,IBM 360/91首先采用了Tomasulo算法。
14、 IBM 360/91的设计目标是基于整个360系列的统一指令集和编译器来实现高性能,而不是设计和利用专用的编译器来提高性能。 需要更多地依赖于硬件。IBM 360体系结构只有4个双精度浮点寄存器,限制了编译器调度的有效性。360/91的访存时间和浮点计算时间都很长。 (也是Tomasulo算法要解决的问题),第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,保留站(reservation station) 每个保留站中保存一条已经流出并等待到本功能部件执行的指令(相关信息)。包括:操作码、操作数以及用于检测和解决冲
15、突的信息。在一条指令流出到保留站的时候,如果该指令的源操作数已经在寄存器中就绪,则将之取到该保留站中。如果操作数还没有计算出来,则在该保留站中记录将产生这个操作数的保留站的标识。浮点加法器有3个保留站:ADD1,ADD2,ADD3浮点乘法器有两个保留站:MULT1,MULT2 每个保留站都有一个标识字段,唯一地标识了该保留站。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,公共数据总线CDB (一条重要的数据通路)所有功能部件的计算结果都是送到CDB上,由它把这些结果直接送到(播送到)各个需要该结果的地方。在具有多个执行部件且采用多流出(即每个时钟周期流出多条指令)的流水线中
16、,需要采用多条CDB。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,load缓冲器和store缓冲器 存放读/写存储器的数据或地址 load缓冲器的作用有3个:存放用于计算有效地址的分量;记录正在进行的load访存,等待存储器的响应;保存已经完成了的load的结果(即从存储器取来的数据),等待CDB传输。store缓冲器的作用有3个:存放用于计算有效地址的分量;保存正在进行的store访存的目标地址,该store正在等待存储数据的到达;保存该store的地址和数据,直到存储部件接收。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,浮点寄存器FP共有16个浮
17、点寄存器:F0,F2,F4,F30。它们通过一对总线连接到功能部件,并通过CDB连接到store缓冲器。指令队列指令部件送来的指令放入指令队列指令队列中的指令按先进先出的顺序流出运算部件浮点加法器完成加法和减法操作浮点乘法器完成乘法和除法操作,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,在Tomasulo算法中,寄存器换名是通过保留站和流出逻辑来共同完成的。当指令流出时,如果其操作数还没有计算出来,则将该指令中相应的寄存器号换名为将产生这个操作数的保留站的标识。指令流出到保留站后,其操作数寄存器号或者换成了数据本身(如果该数据已经就绪),或者换成了保留站的标识,不再与寄存器
18、有关系。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,Tomasulo算法具有以下两个特点:冲突检测和指令执行控制 是分布的。 每个功能部件的保留站中的信息决定了什么时候指令可以在该功能部件开始执行。计算结果通过CDB直接从产生它的保留站传送到所有需要它的功能部件,而不用经过寄存器。,第四章 指令级并行指令的动态调度 Tomasulo算法基本思想,使用Tomasulo算法的流水线需3段:流出:从指令队列的头部取一条指令。如果该指令的操作所要求的保留站有空闲的,就把该指令送到该保留站(设为r)。如果其操作数在寄存器中已经就绪,就将这些操作数送入保留站r。如果其操作数还没有就绪
19、,就把将产生该操作数的保留站的标识送入保留站r。一旦被记录的保留站完成计算,它将直接把数据送给保留站r。(寄存器换名和对操作数进行缓冲,消除WAR冲突)完成对目标寄存器的预约工作 (消除了WAW冲突)如果没有空闲的保留站,指令就不能流出。 (发生了结构冲突),第四章 指令级并行指令的动态调度 Tomasulo算法执行顺序,执行 当两个操作数都就绪后,本保留站就用相应的功能部件开始执行指令规定的操作。 load和store指令的执行需要两个步骤:计算有效地址(要等到基地址寄存器就绪)把有效地址放入load或store缓冲器写结果 功能部件计算完毕后,就将计算结果放到CDB上,所有等待该计算结果的
20、寄存器和保留站(包括store缓冲器)都同时从CDB上获得所需要的数据。,第四章 指令级并行指令的动态调度 Tomasulo算法执行顺序,例4.1 对于下述指令序列,给出当第一条指令完成并写入结果时,Tomasulo算法所用的各信息表中的内容。 L.DF6,34(R2) L.DF2,45(R3) MUL.DF0,F2,F4 SUB.DF8,F2,F6 DIV.DF10,F0,F6 ADD.DF6,F8,F2,第四章 指令级并行指令的动态调度 Tomasulo算法执行顺序,第四章 指令级并行指令的动态调度 Tomasulo算法执行顺序,名称,保留站,Load1Load2Add1Add2Add3M
21、ult1Mult2,Busy no yes yes yes no yes yes,Op LD SUB ADD MUL DIV,Vj,Vk Mem34+RegsR2 RegF4 Mem34+RegsR2,Qj Load2 Add1 Load2 Mult1,Qk Load2,A 45+RegsR3,Tomasulo算法具有两个主要的优点:冲突检测逻辑是分布的 (通过保留站和CDB实现)如果有多条指令已经获得了一个操作数,并同时在等待同一运算结果,那么这个结果一产生,就可以通过CDB同时播送给所有这些指令,使它们可以同时执行。消除了WAW冲突和WAR冲突导致的停顿 使用保留站进行寄存器换名,并且操作数一旦就绪就将之放入保留站。注意: 指令是按照程序的顺序流出的,但是不一定按照程序顺序执行。,第四章 指令级并行指令的动态调度 Tomasulo算法执行顺序,