这是计算机系统结构复习内容的第二部分,第一部分请转链接:https://blog.csdn.net/zongza/article/details/83780572
往期回顾:
Part 1(chapter 1 - chapter 5):https://blog.csdn.net/zongza/article/details/83780572
Part 2(chapter 5 - chapter 10):https://blog.csdn.net/zongza/article/details/83933327
Part 3(概念专辑):https://blog.csdn.net/zongza/article/details/84100133
Part 4(习题专辑):https://blog.csdn.net/zongza/article/details/84111578
资料下载:
计算机体系结构-量化研究方法-Hennessy&Patterson著(英文版):https://download.csdn.net/download/zongza/10787837
计算机体系结构-量化研究方法-Hennessy&Patterson著(中文版):https://download.csdn.net/download/zongza/10787840
计算机系统结构教程-第二版-张晨曦著:https://download.csdn.net/download/zongza/10787843
计算机体系结构教程-学习指导与题解:https://download.csdn.net/download/zongza/10793886
nBranch Target Buffers 分支目标缓冲 *
nConcept and Advantages of Dynamic Scheduling * 动态调度
- qScoreboard 记分牌
- qTomasulo
- qSpeculation 前瞻执行
- qTomasulo with ReOrder Buffer 再定序缓冲
nSuperscalar and VLIW * 超标量与超长指令字
动态是相对静态而言的,静态是指通过编译器(软件)进行调度,也就是在运行前进行调度,不可更改,动态调度是通过硬件实现在指令执行过程中的调度,同时还能保证data flow和exception behavior。
优点:
关键思想:允许被stall的指令停顿期间执行后面的指令(顺序发射,乱序执行,乱序完成)
DIVD F0,F2,F4
ADDD F10,F0,F8
SUBD F12,F8,F14
比如:DIVD和ADDD之间有RAW,因此ADDD被stall,此时SUBD和两者不存在任何相关和冲突,因此硬件可以在ADDD的stall期间执行SUBD
具体实现:将ID段拆成两个:Issure 和 Read operands,前者检测结构冲突,只要没有SH,该指令就能发射;后者检测数据冲突,等到没有DH就可以读操作数
但是,这种方式可能会带来WAR和WAW冲突:
DIVD F10,F0,F2
ADDD F10,F4,F6
SUBD F6,F8,F14
如果不对ADDD和SUBD使用寄存器重命名,那么因为SUBD和ADDD存在反相关(F6)如果流水线在ADDD读出F6之前就能完成SUBD,就回出现错误。类似的,DIVD和SDDD存在输出相关,流水线必须能检测出该相关,并避免WAW冲突。(可以用寄存器重命名解决)
记分牌通过记录指令执行过程中指令的状态,运算部件的状态,寄存器的状态实现集中控制(centralized control),其中记分牌只记录四种指令状态:
记录的三种状态各自有一个表:如下所示
- 指令状态表特点:四个段 :发射 读取 执行 写回
- 功能部件状态表特点: 1+2+2+2
- 寄存器状态表特点:对应功能部件(一对一?)
下图显示了第二条LD指令准备写结果之前的三表状态:
指令状态表:
- 此时LD2 处于EX阶段,由于MUL SUB 与LD2有数据相关(F2,RAW)所以两者都只能过issue(无结构冲突)不能进入Read。
- 由于MUL和DIV有数据相关(F0,RAW)所以DIV同理也只能在Issue阶段。
- ADD与SUB有结构冲突(争用加法器)所以连发射都不行。
功能单元状态表:
Fi 目的寄存器 Fj Fk 源寄存器 Qj Qk 源寄存器的来源(来自哪个功能部件) Rj Rk (yes表示就绪待取,no表示取完或者未就绪)
- Integer的Rj表示取完。
- Mult1的Rj表示没就绪,Rk表示就绪待取
寄存器状态表:
- 表示存到F0寄存器的结果来自功能部件Mult1
下图显示了MULT指令准备写结果之前的状态:
- 由于SUB和MUL不存在任何冲突和相关,且SUB 2cycles,MUL 10cycles 因此当MUL到了EX段,SUB一定执行完了
- MUL和DIV有RAW(F0),所以MUL没吧结果写到F0之前DIV只能处于Issue
- DIV和ADD有WAR(F6),所以DIV没读F6之前ADD必须阻塞在EX段
下图显示了DIV指令准备写结果之前的状态:
- DIV写结果前,前面的指令一定都完成了
- DIV要40个周期,ADD只要两个,因此当DIV取走F6后ADD立刻执行完全有足够的时间赶在DIV前面完成。
总结:
主要思想:
- 将保留站作为虚拟寄存器存储 指令和操作数,实现分布式控制和缓存
- 记录和检测指令相关,功能单元直接从保留站获得操作数(不再从寄存器读),操作数一旦就绪就立即执行,减少RAW(因为读操作的源已被定向(预约)到写的指令,只有操作数就绪时读才执行);
- 通过寄存器换名来消除WAR冲突和WAW冲突。寄存器换名是通过保留站和流出逻辑来共同完成的。(之后的写操作对保留站中的指令不再有影响,因为已换名,也就是指令中寄存器号换成了产生这个操作数的保留站标识,操作数可从CDB得到,不用再从寄存器读)
可见:
优点:
- 冲突检测逻辑是分布的(通过保留站和CDB实现)
- 消除了WAR和WAW冲突
缺点:
- 实现复杂
- 需要大量的高速相联存储
- 性能受CDB影响大(解决:多CDB)
下面是采用DLX浮点部件的Tomasulo算法执行过程中用到的状态表,试填写状态表中的相关空白。 假定:浮点流水线的延迟如下:加法2个时钟周期,乘法10个时钟周期,除法40个时钟周期。给出SUBD 将要写结果时状态表的信息。只填写相关部分空格。
指令 |
指令状态表 |
||
IS |
EX |
WR |
|
LD F6,34(R2) |
√ |
√ |
√ |
LD F2,45(R3) |
√ |
√ |
√ |
MULTD FO,F2,F4 |
√ |
|
|
SUBD F8,F6,F2 |
√ |
√ |
|
DIVD F10,F0,F6 |
√ |
|
|
ADDD F6,F8,F2 |
√ |
√ |
|
部件 名称 |
保留站 |
||||||
Busy |
Op |
Vj |
Vk |
Qj |
Qk |
A |
|
Load1 |
no |
|
|
|
|
|
|
Load2 |
no |
|
|
|
|
|
|
Add1 |
yes |
SUBD |
Mem[45+Regs[R3]] |
Mem[34+Regs[R2]] |
|
|
|
Add2 |
yes |
ADDD |
|
Mem[45+Regs[R3]] |
Add1 |
|
|
Add3 |
no |
|
|
|
|
|
|
Mult1 |
yes |
MULTD |
Mem[45+Regs[R3]] |
Regs[4] |
|
|
|
Mult2 |
yes |
DIVD |
|
Mem[34+Regs[R2]] |
Mult1 |
|
|
|
结果寄存器状态表 |
|||||||
F0 |
F2 |
F4 |
F6 |
F8 |
F10 |
…… |
F30 |
|
部件名称 |
Mult1 |
|
|
Add2 |
Add1 |
Mult2 |
…… |
|
前瞻:循序处理器还未判断指令是否能执行之前就提前执行,以克服控制相关。他的实质是数据流执行:只要操作数就绪,指令就执行。
与流水线中的静态分支预测区别:前瞻技术是依靠硬件+动态分支预测技术+动态调度实现的。
前瞻是为了让动态调度算法更好地处理分支指令(有控制相关)。tomasulo的指令完成和写结果都在WR段,而在前瞻执行中加以区分,分成两个不同的段:写结果,指令确认,特点是:允许指令乱序执行,但是必须顺序确认(注意不是顺序完成,确认是顺序的,但是完成可以乱序)。
写结果段:前瞻执行的结果写到ROB,并通过CDB传递ROB中的结果到需要他们的指令保留站。
指令确认段:在分支结果出来后,对相应的前瞻执行结果予以确认,如果前瞻是对的,就把ROB中的结果写到寄存器或者存储器,如果是错的,就不予以确认并从那条分支指令的另一条路径重新开始执行。
ROB的每一项:
指令类型(指出该指令是分支指令、store指令或寄存器操作指令)+目标地址( 给出指令执行结果应写入的目标寄存器号(如果是 load和ALU指令)或存储器单元的地址(如果是store指令))+ 数据值字段(用来保存指令前瞻执行的结果,直到指令得到确认)+就绪字段( 指出指令是否已经完成执行并且数据已就绪)+控制字段(设置ROB的某一项是否被占用)
普通tomasulo和带有前瞻的tomasulo对比:
前面的方法可以提高并行度,但是CPI不可能低于1(最多就是1),想要在一个周期流出(发射)多条指令就得用多指令流出技术,包括超标量和超长指令字两种方法.
超标量和超长指令字都是指具有每个周期多指令流出能力的计算机。他们的区别在于调度方式(动态or静态)。.
通过编译器进行调度+流出指令时用单独硬件检测冲突 == 静态调度+动态流出(所谓动态流出是指流出包中的指令可能不会全部流出,比如某指令与其他存在冲突,就只流出该指令之前的指令)
MIPS中的静态超标量实例:
这里是2-流出超标量,每个时钟周期流出1条整型指令和1条浮点指令(load store 分支看做整型)
超标量中的循环展开:
需要考虑的问题:LD和ADD之间要有一个时钟的延迟,ADD和SD之间要有两个时钟的延迟
那么如果只展开四次ADD和SD的延迟不可避免,解决方法是进行更多的展开(5次)
通过硬件进行调度+两个tomasulo控制器(整型和浮点,确保不会乱序流出)== 动态调度+动态流出
完全靠编译器进行调度 == 静态调度+静态流出(所谓静态流出是指每个时钟周期流出的指令数是固定的,这些指令构成一个长指令或指令包)
VLIW中的循环展开(指令包长度=2+2+1,注意其中某个指令槽不一定会被填满):
9 clocks/ 7 iterations = 1.3clock_per_interation
总结:
硬件的分支预测能力好,所需的代码少,但是需要大量的硬件
软件的推断设计简单,所需硬件少,但是代码量大
nWhat are Limits to ILP
nWhat is instruction window? 指令窗口
nWhat is Thread Level Parallelism (TLP) or MultiThreading * 线程级并行,多线程
nWhat is Data Level Parallelism? 数据级并行
How to switch Multi Threads *
- qfine grain 细粒度切换
- qcoarse grain 粗粒度切换
nWhat is Simultaneous multithreading * 同时多线程
nKnow something about Power5
硬件完善度只要体现在以下四个方面:
指等待被检测是否能同时发射的指令总数,大小和检测冲突所需的代价有关(50个指令就需要2500次检测),也和cpu存储大小有关(窗口中的指令都是在处理器中)
线程:一个小型的进程,有自己的指令和数据,可以独立执行。线程可以是独立的部分也可以是并行程序中的一小段。
线程级并行是比指令级并行更高的层次,他可以显式地将几个线程并行执行(他们之间共享执行单元)。
数据级并行是比指令级并行更低的层次,他允许单一指令对多个操作数进行计算(SIMD)
我们考虑下面这个计算式子:(a+b)*(c+d)
该计算过程被分解为三步:
1. e = a +b
2. f = c +d
3. m = e * f
早期的计算机一次只能处理一条指令,它要先算步骤1(加法操作),再算步骤2(加法操作),最后算3(乘法操作)。需要三步(花费三个指令)得到答案。
但是我们观察到:
3的结果依赖于1和2,而1和2都单纯的加法操作,所以开始想办法让1和2同时计算,那么CPU只要两步得到答案,步骤1和2一次算出来的结果,直接进行乘法运算。
它运用了SIMD
(Single -Instruction ,Multple -Data)单指令多数据流
技术。一个指令执行了(a,b,c,d) 4个操作数。SIMD指令集可以提供更快的图像,声音,视频数据等运行速度。
指令级并行是一种隐式并行,也就是写程序的人不需要关注,通过流水线和超标量,使得一个程序的指令序列中有多条同时乱序运行,顺序提交。这依赖寄存器重命名,多个执行单元,重排序缓冲和指令预测技术。
线程级并行时一种显式并行,也就是程序员要写多线程程序。线程级并行主要指同时多线程(SMT)/超线程(HT)以及多核和多处理器。SMT是在指令级并行的基础上的扩展,可以在一个核上运行多个线程,多个线程共享执行单元,以便提高部件的利用率,提高吞吐量。SMT需要为每个线程单独保持状态,如程序计数器(PC),寄存器堆,重排序缓冲等。
数据级并行是一种显式并行,主要指单指令多数据(SIMD),比如a,b和c都是相同大小的数组,要进行的计算是a的每一个元素与b的响应元素进行运算,结果放入c的对应元素中。如果没有SIMD,就需要写一个循环执行多遍来完成,而SIMD中 一条指令就可以并行地执行运算。 线程的概念就是程序的执行序,每个执行序有执行上下文需要保存。
ILP的过程中很多功能单元处于闲置状态(由于stall或者相关)这时候就可以在闲置期开发TLP,具体来说就是把其他线程的指令看做不相关指令,并在stall期间执行。
硬件支持:
SMT的缺点:
nLevels of the Memory Hierarchy * 存储系统的层次结构
nThe Principle of Locality: Temporal Locality and Spatial Locality * 局部性原理
nWhere can a block be placed: Fully associative, direct mapped, n-way set associative * 映像规则
nHow is a block found in the upper level? 查找算法
nWhich block should be replaced on a miss? 替换算法:Random、LRU、FIFO
nWrite Policy: Write-Through and Write-Back; Write allocate and No-write allocate * 写策略:写直达与写回,按写分配与不按写分配
nWhat and Why a write buffer 写缓存
80年代CPU速度提升很快而DRAM的速度相对发展缓慢,因此处理器和存储器之间的速度gap越来越大。
为了解决这个问题就有了cache,他作为存储器的一个缩放,工作在CPU和存储器之间,使得程序可以像访问寄存器一样快速访问cache,缓解CPU和DRAM速度差异。
常见的五级存储结构:
寄存器-> cache -> memory(主存) -> disk(辅存) -> tape
局部性原理是程序能进行随机性访问的基础
时间局部性:当前某项被访问,那么近期他可能还会被访问
空间局部性:当前某项被访问,那么他附近的项也可能被访问
如何确定Cache中是否有所要访问的块?
答案:查找目录表!
CPU和cache的交互如下所示:
可知写操作必须在确认是命中后才可进行,因此将写策略分成两部分讨论:
当write miss时(要写的部分不再data cache里):
当write hit时:
常用组合:
写直达中因为要同时写cache和主存因此有了写缓存,减少CPU停顿
nCache Measures: Average memory-access time ** Cache性能:平均访问时间,命中与失效
- q= Hit time + Miss rate x Miss penalty *
- q= Hit timeL1+ Miss rateL1x (Hit timeL2+ Miss rateL2x Miss penaltyL2)
nBasic Cache Optimizations
nThree Major Categories of Cache Misses: Compulsory, Capacity and Conflict * 强制、容量与冲突不命中
nWhat is virtual address space 虚存空间
nHow page table works 页表
nTranslation Look-Aside Buffer (TLB)地址变换后备缓存
cache优化从平均访问时间公式中的的三个要素入手
虚存定义:由主存和辅存构成,通过必须的软件(页表)和硬件(地址转换)支持,使得cpu访问的存储器可以有主存的速度和辅存的容量。
其中sharing指 :每个用户有一个页表 ,每一个用户页在页表中有一行,操作系统确保不同的页表不交叠(如下所示)
32位虚地址空间(按照字节寻址),每页4KB,页表每项4字节(32bit),页表大小是?
Given a 32-bit virtual address,4 KB pages, and 4 bytes per Page Table Entry (PTE), the size of the page table would be ?
首先页表有 2^32B / 2^12B 个项,每项大小是4B(4B的PTE),所以页表总大小为两者积=4MB。
每个进程都要有自己的页表,每个页表要4MB,页表可能太多无法装入内存(页表存在内存中 ),所以有了二级页表:
一级页表索引了1K(1024)个二级页表,他们都在主存中,后面白的对应辅存中的实际块。
目的:减少地址变换的时间(页表在主存,每次data/instruction都要两次访问内存,一次查页表一次取d/i,时间长)
TLB相当于一个全相连的cache,CPU直接查TLB,比查页表快得多
会有同义字问题:如果两个虚地址指向同一个实地址,那么cache中会有两个相同的块,浪费资源的同时也很难维持数据一致性
以Bs=16为例:64k的cache 缺失率为2.04%,所以命中率为1-2.04%
平均存取时间 = hit_time + miss_rate*(miss_pernalty) = 1+ 2.04%*(62)
如果Bs = 32:
平均存取时间 = hit_time + miss_rate*(miss_pernalty) = 1+ 1.35%*(64)
nWhat is a bus? Types of Buses
nDisk Drive Performance
nReliability, Availability and Dependability of the Storage Device * 可靠性、可用性与可信性
- qMTTF, MTTR and MTBF
nRedundant Arrays of Inexpensive Disks (RAID): Type, Characteristics and Read/Write Algorithm ** 廉价磁盘冗余阵列
nI/O Benchmarks: Metrics and TPC
总线就是共享的通信链路,连接多个子系统
服务时间 = 找道时间+旋转时间+数据传输时间
基本思想:将多个容量较小、相对廉价的磁盘进行有机组合,从而以较低的成本获得与昂贵大容量磁盘相当的容量、性能、可靠性。
这种disk array的思想可以明显提高存储容量以及IO率,但是可靠性大大降低(反映在MTTF低),如下图所示:
70个IBM3.5虽然获得了9倍于3390k的容量和6倍的IO率,但是MTTF却从6年降低到1个月(new_MTTF=6年/70盘)
解决方法:数据被视为由多个条带组成(如下下图RAID 0 所示),这些条带分布存储在不同disk,因此可以利用冗余信息(redundancy),来提高设备的可用性
注意disk仍会有故障(也就是可靠性不变)但是由于其他没故障的disk有备份数据(此时冗余信息为备份信息)或者可以计算出丢失的数据(此时冗余信息为校验信息,可以结合无故障的数据计算出丢失的信息),所以整体服务没有中断(可用性),这种做法也有缺点:
- 容量损失:为了存冗余信息占用空闲disk
- 带宽损失:为了更新冗余信息占用带宽
RAID0 基本思想:
RAID1 基本思想:
读写特点:
逻辑读 = 一次读操作
逻辑写 = 两次写操作
基本思想:冗余信息不再是备份,而是对条带中逻辑位的校验信息,只可容忍单盘除错。
校验信息是条带中所有位的和。下图冗余代价为1/3=33%。利用率为3/4。
读写特点:
逻辑读 = 五次读操作
逻辑写 = 三次读操作(计算新的校验位)+两次写操作(写目标数据和检验数据)
缺点: 一次磁盘访问(读或写)需要对阵列中所有磁盘进行操作【解决:RAID4】
基本思想:条带中的信息由位变成块,每个扇区有自己的检错码,因此读操作不会访问校验盘和其他数据盘,使得每个磁盘可以独立地进行读,提高并行度。
读写特点:
逻辑读 = 一次读操作
逻辑写 = 两次读操作(计算新的校验位)+两次写操作(写目标数据和检验数据)
缺点:多个盘同时进行写操作时,P盘的IO压力较大(每个盘的写都要重写P,而且重写必须串行)【解决:RAID5】
基本思想:检验块均匀分布在所有磁盘上,(而不是单独指定校验盘)这样在写操作修改P的时候不同盘的写可以并行(因为要修改的P不一样了,RAID4中写入D0 D5 需要串行得写disk4(唯一的P),RAID5中可以并行地写disk3,4)。
读写特点:
逻辑读 = 一次读操作
逻辑写 = 两次读操作(计算新的校验位)+两次写操作(写目标数据和检验数据)
缺点: 只能纠错检错一个盘【解决:RAID6】
基本思想:在RAID5的基础上再增加一个均匀分布的检验块,(两个独立的奇偶系统使用不同的算法)从而容忍双盘出错。
参考:https://www.cnblogs.com/chuncn/p/6008173.html
读写特点:
逻辑读 = 一次读操作
逻辑写 = 三次读操作(计算新的校验位)+三次写操作(写目标数据和检验数据)
缺点:写性能损失太大。
nClassifications of Computers (IEEE) * 计算机分类
nFlynn’s Taxonomy * Flynn分类法
nWhy Vector Computers? * 冲突在哪里?
nVector Programming Model and SIMD extensions *
nHow Vector Processors Work: deep pipeline and multiple independent memory banks
nWhat is Vector Strip-mining 分段开采技术
nWhat is Vector Stride 向量跨距/步长
nMulti-processors & Multi-computers *多处理机与多计算机
基本思想:根据指令流和数据流的多倍性进行分类
值得注意的是SIMD就是前面的数据级并行,MIMD就是线程级并行。
下图显示了MIMD的扩展分类,其中红圈为常用的 架构(多核+共享存储 与 多计算机+分布存储).
A = [a1 , a2, a3, ..., an]
B = [b1 , b2, b3, ..., bn]
a1 a2..之间是相互独立的,但是a1和b1之间可能存在冲突.
因为MM架构的读和写全都在内存,所以会主存带宽要求高,同时由于冲突检测需要在内存进行,因此并行性能低,初始化的时延高,所以MM已经被淘汰了.
分段开采:当向量长度大于向量寄存器的长度时,必须把长向量分成长度固定的段,然后循环分段处理,每次只处理一个向量段。(分段操作是系统自动完成,对程序员透明)
例如N = 68,则循环次数为N / 64 =1 ,余数为4,在循环开始前要先对余数个元素进行计算(Remainder段)
向量步长:mem中向量要提取部分的元素之间的距离 。
例如下面的矩阵乘法中,B的每一行要和C的每一列相乘,矩阵在mem中都是顺序存储的,这就意味着B和C一定有一个不能顺序读出,此时对于不能顺序读出的(假设按照行优先存储)就需要利用stride来提取C中对应的列元素。
下图反映了从mem中使用stride提取向量部分元素值的情况。
链接技术相当于流水线定向技术在向量处理机中的应用。
向量流水线链接:有RAW相关的两条指令,在不出现功能部件冲突和其他冲突的情况下,可以把功能部件链接起来进行流水处理。
MIMD分成两种:
多核: 基于共享存储器(shared memory),所有处理器共享同一地址空间 ,由load和store实现通信
多计算机: 基于消息传递(message passing),每个处理器有私有局部存储器,处理器之间以传递消息的方式传递数据
nWhat is Computer cluster, SMP, MPP? * 机群、对称式共享存储多处理机、大规模并行处理机
nFlynn-Johnson classification **
n2 classes of multiprocessors with respect to memory: *
- qCentralized Memory Multiprocessor 集中式存储器
- qPhysically Distributed-Memory Multiprocessor 分布式存储器
n2 Models for Communication: *
- qmessage-passing 消息传递
- qShared memory 共享存储
nChallenges of Parallel Processing ** 计算
集群: 是一组通过本地高速网络互联的计算机机群,他们可以一起工作.
SMP: 是指使用集中式共享存储器的多核计算机(所谓对称是指MEM与所有处理器的关系都一样)
MPP: 是由成百上千台处理器组成的大规模并行计算机系统
多核的共享存储器可以有两种实现:
集中式存储 分布式存储
对比:
分布式优点:
- 减少互联网络的带宽占用(如果大多数访存都是针对本地mem)
- 本地存储器访问时延低
分布式缺点:
- 处理器间的通信复杂
- 需要好的软件调度来充分利用增加的带宽
- 处理器之间的访问时延高
消息传递 和 共享存储 (具体见上一chapter内容)
计算题