HW3
[!ABSTRACT]
3220104929 241117
##
[!TIP] 假设
取指、译码和发射共用同一个周期,WB 需要一个周期
所有的指令都在同一个 FU 执行,但是不同指令有不同的 latency
###
Inst | IF/IS | FU | WB |
---|---|---|---|
Loop 右边的 fld |
0 | 1 | 5 |
I0 | 1 | 6 | 11 |
I1 | 6 | 12 | 23 |
I2 | 12 | 24 | 28 |
I3 | 24 | 29 | 32 |
I4 | 29 | 33 | 36 |
I5 | 33 | 37 | 39 |
I6 | 37 | 40 | 41 |
I7 | 40 | 42 | 43 |
I8 | 42 | 44 | 45 |
I9 | 44 | 46 | 48 |
###
记 I1.f2 $\rightarrow $ I0.f2 表示 I1 的 f2 依赖于 I0 的 f2
I0.f2 $\rightarrow $ loop(fld).f2
I1.f2 $\rightarrow $ I0.f2
I3.f4 $\rightarrow $ I2.f4
I4.f2 $\rightarrow $ I0.f2
I4.f8 $\rightarrow $ I1.f8
I5.f4 $\rightarrow $ I3.f4
假设有 无限个 Function unit,表格将变为:
Inst | IF/IS | FU | WB |
---|---|---|---|
Loop 那个 fld |
0 | 1 | 5 |
I0 | 1 | 6 | 11 |
I1 | 6 | 12 | 23 |
I2 | 12 | 13 | 17 |
I3 | 13 | 18 | 21 |
I4 | 18 | 24 | 27 |
I5 | 24 | 25 | 27 |
I6 | 25 | 26 | 27 |
I7 | 26 | 27 | 28 |
I8 | 27 | 28 | 29 |
I9 | 28 | 29 | 31 |
###
假设一次能发射两条指令,FU 数量仍为无限个:
Inst | IF/IS | FU | WB |
---|---|---|---|
Loop 那个 fld |
0 | 1 | 5 |
I0 | 0 | 6 | 11 |
I1 | 1 | 6 | 17 |
I2 | 7 | 8 | 12 |
I3 | 7 | 13 | 16 |
I4 | 8 | 18 | 21 |
I5 | 13 | 17 | 19 |
I6 | 17 | 18 | 19 |
I7 | 18 | 19 | 20 |
I8 | 18 | 19 | 20 |
I9 | 19 | 20 | 22 |
##
[!QUESTION]
介绍一下 VLIW 技术,谈一下他是怎么解决 RAW 和 WAR 冒险的,他的优缺点在哪
[!IMPORTANT] 发现照抄 GPT 的视为 0 分
VLIW 技术
程序的 CPU 执行时间 = 指令数 × CPI × Clock Cycle Time,后两者在我们的单发 CPU 框架下已经很难再继续减低了,所以我们可以尝试改进前者——增加 IPC,VLIW 技术就是基于此思路诞生的一种“史诗级”失败的技术(EPIC)
VLIW 即 Very Long Instruction Word,超长指令字设计
这项技术的大致思路是:
- 我们可以让编译器把没有依赖关系的代码位置进行交换,把多条连续的无依赖关系的指令打包成一个指令包 Group
- fetch 和 decode 阶段的的基本单元变成了 Group
- Group 里的所有指令可以一口气丢给 FU 执行
- 依赖关系的检测由特别的编译器在编译时完成
RAW 和 WAR 冒险解决
RAW 靠编译器分析依赖关系来解决,每个 Group 内的指令无依赖关系,有无法规避的情况会插入 NOP
WAR 也是靠编译器分析依赖关系来解决
优缺点
- 优点
- 不需要动态调度硬件,硬件简化了很多
- 指令能并行执行
- 缺点
- 十分依赖编译器,编译器要求高
- 编译器兼容性差,硬件参数稍微改改就用不了了
- 一个 Group 里最长的指令执行完才能执行下一个 Group,还有提升空间
##
[!IMPORTANT] 本题需要给出过程,否则不给分。
###
cycle | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
lw x3,0(x0) | F | D | E | E | E | M | W | ||||||||||||||
lw x1,0(x3) | F | D | S | S | E | E | E | M | W | ||||||||||||
addi x1, x1,1 | F | D | S | S | S | S | S | E | M | W | |||||||||||
sub x4, x3, x2 | F | D | S | S | S | S | S | E | M | W | |||||||||||
sw x1,0(x3) | F | D | S | S | S | S | S | E | E | E | M | W | |||||||||
bnz x4, Loop | F | D | S | S | S | S | S | S | S | E | E | M | W | ||||||||
lw x3,0(x0) | F | D | E | E | E |
上图错了,stall 是不会有新的指令进入的
clock cycles per loop iteration are lost to branch overhead = 10
###
Backward Branch(向后分支)指的是分支目标地址在当前指令地址之前的情况,本题目代码中的 bnz
指令即属于这种 branch,故题目给的 static branch predictor 可以预测出 bnz
的结果
所以 clock cycles are wasted on branch overhead = 0
错了,浪费了 IF 和 ID 这 2 个 cycle
由于题目没给出内存中数据情况,在这里假设 0(x0) 和各寄存器一开始的值都是 0
如果预判成功,clock cycles are wasted on branch overhead = 0