三道题理解软件流水
</head>
</body>
什么是软件流水 | ||||||||
软件流水是一种变相的循环展开,是利用不同循环间语句无相关的特点消除流水线阻塞的技术。和循环展开一样,软流水不更改程序的执行顺序和执行次数。 | ||||||||
第一题 | ||||||||
已知跳转指令有延迟槽,请将下面的循环体进行软件流水,其中(R2)=0,(R1) = 8*n。 | ||||||||
L1: LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,0(R1) | ||||||||
ADDIU R1,R1,-8 | ||||||||
BNE R1,R2,L1 | ||||||||
NOP | ||||||||
1. 展开对齐,本题有2次RAW相关,故展开3次 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | LDC1 F0,-8(R1) | |||||||
SDC1 F2,0(R1) | ADD.D F2,F0,F1 | LDC1 F0,-16(R1) | ||||||
SDC1 F2,-8(R1) | ADD.D F2,F0,F1 | |||||||
SDC1 F2,-16(R1) | ||||||||
2. 绿色是装入代码,蓝色排空代码,黄色是软流水循环主体,按顺序抄下来 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
L1: SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-16(R1) | ||||||||
SDC1 F2,-8(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,-16(R1) | ||||||||
3. 加入原循环中除主体循环以外的指令 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
L1: SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-16(R1) | ||||||||
BNE R2,R1,L1 | ||||||||
ADDIU R1,R1,-8 | 这条指令下面R1的下标值统统+8 | |||||||
SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,-8(R1) | ||||||||
4. 在装入代码中加入语句保证指令顺序和数量与原循环一致 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
ADDIU R1,R1,-24 | 用特例法: n=3时,原代码会循环3次,软流水装入代码+循环主体+排空代码相当于循环展开了3次,所以n=3时软流水的跳转指令不应跳转。 为保证n=3,R1=24时,软流水的跳转指令不跳转,应在装入代码里改变R1的值让第一次跳转指令判断时R1的值为0。 由于下面的ADDIU指令被放到了延迟槽内,不会影响跳转指令判断,为保证第一次跳转指令判断时R1的值为0,应-24。 这条指令下面R1的下标值统统+24,以保证下标正确 |
|||||||
L1: SDC1 F2,24(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,8(R1) | ||||||||
BNE R1,R2,L1 | ||||||||
ADDIU R1,R1,-8 | ||||||||
SDC1 F2,24(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,16(R1) | ||||||||
第二题 | ||||||||
跳转指令没有延迟槽,延迟为一拍,请将下面的循环体进行软件流水,其中(R2)=0,(R1) = 8*n。 | ||||||||
L1: LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,0(R1) | ||||||||
ADDIU R1,R1,-8 | ||||||||
BNE R1,R2,L1 | ||||||||
NOP | ||||||||
1. 展开对齐,本题有2次RAW相关,故展开3次 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | LDC1 F0,-8(R1) | |||||||
SDC1 F2,0(R1) | ADD.D F2,F0,F1 | LDC1 F0,-16(R1) | ||||||
SDC1 F2,-8(R1) | ADD.D F2,F0,F1 | |||||||
SDC1 F2,-16(R1) | ||||||||
2. 绿色装入,蓝色排空,黄色软流水循环主体,按顺序抄下来 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
L1: SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-16(R1) | ||||||||
SDC1 F2,-8(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,-16(R1) | ||||||||
3. 加入原循环中除主体循环以外的指令并调整下标值 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
L1: SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-16(R1) | ||||||||
ADDIU R1,R1,-8 | 这条指令下面R1的下标值统统+8 | |||||||
BNE R2,R1,L1 | ||||||||
NOP | ||||||||
SDC1 F2,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,-8(R1) | ||||||||
4. 在装入代码中加入语句保证指令顺序和数量与原循环一致,并调整下标值 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,-8(R1) | ||||||||
ADDIU R1,R1,-16 | 用特例法: n=3时,原代码会循环3次,软流水装入代码+循环主体+排空代码相当于循环展开了3次,所以n=3时软流水的跳转指令不应跳转。 为保证n=3,R1=24时,软流水的跳转指令不跳转,应在装入代码里改变R1的值让第一次跳转指令判断时R1的值为0。 由于下面的ADDIU指令会-8且影响跳转指令判断,为保证第一次跳转指令判断时R1的值为0,应-16。 这条指令下面R1的下标值统统+16,以保证下标正确 |
|||||||
L1: SDC1 F2,16(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
LDC1 F0,0(R1) | ||||||||
ADDIU R1,R1,-8 | ||||||||
BNE R1,R2,L1 | ||||||||
NOP | ||||||||
SDC1 F2,16(R1) | ||||||||
ADD.D F2,F0,F1 | ||||||||
SDC1 F2,8(R1) | ||||||||
第三题 | ||||||||
跳转指令有延迟槽,跳转指令的延迟为一拍,请将下面的循环体进行软件流水,其中(R1) = 0 | ||||||||
b: LDC1 F2, 0(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, 0(R2) | ||||||||
DADDIU R1, R1, 8 | ||||||||
DADDIU R2, R2, 8 | ||||||||
DSGTUI R3, R1, 800 | // R1 == 800 ? R3 = 0 : R3 = 1 | |||||||
BEQZ R3, b | ||||||||
NOP | ||||||||
1. 展开对齐,本题有3次RAW相关,故展开4次,没有RAW相关的两句指令可以看成是一句 | ||||||||
LDC1 F2, 0(R1) | ||||||||
MUL.D
F4, F2, F0 LDC1 F8, 0(R2) |
LDC1 F2, 8(R1) | |||||||
ADD.D F6, F4, F8 | MUL.D
F4, F2, F0 LDC1 F8, 8(R2) |
LDC1 F2, 16(R1) | ||||||
SDC1 F6, 0(R2) | ADD.D F6, F4, F8 | MUL.D
F4, F2, F0 LDC1 F8, 16(R2) |
LDC1 F2, 24(R1) | |||||
SDC1 F6, 8(R2) | ADD.D F6, F4, F8 | MUL.D
F4, F2, F0 LDC1 F8, 24(R2) |
||||||
SDC1 F6, 16(R2) | ADD.D F6, F4, F8 | |||||||
SDC1 F6, 24(R2) | ||||||||
R2的值不影响循环次数,但是会影响循环的正确执行,所以也要跟着R1的值变化。 | ||||||||
2. 绿色装入,蓝色排空,黄色软流水循环主体,按顺序抄下来 | ||||||||
LDC1 F2, 0(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
LDC1 F2, 8(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 8(R2) | ||||||||
LDC1 F2, 16(R1) | ||||||||
b: SDC1 F6, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 16(R2) | ||||||||
LDC1 F2, 24(R1) | ||||||||
SDC1 F6, 8(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, 16(R2) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 24(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, 24(R2) | ||||||||
3. 加入原循环中除主体循环以外的指令并调整下标值 | ||||||||
LDC1 F2, 0(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
LDC1 F2, 8(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 8(R2) | ||||||||
LDC1 F2, 16(R1) | ||||||||
b: SDC1 F6, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 16(R2) | ||||||||
LDC1 F2, 24(R1) | ||||||||
DADDIU R1, R1, 8 | 这条指令下面R1的下标值统统-8 | |||||||
DADDIU R2, R2, 8 | 这条指令下面R2的下标值统统-8 | |||||||
DSGTUI R3, R1, 800 | ||||||||
BEQZ R3, b | ||||||||
NOP | ||||||||
SDC1 F6, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, 8(R2) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 16(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, 16(R2) | ||||||||
4. 在装入代码中加入语句保证指令顺序和数量与原循环一致,并调整下标值 | ||||||||
LDC1 F2, 0(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 0(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
LDC1 F2, 8(R1) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, 8(R2) | ||||||||
LDC1 F2, 16(R1) | ||||||||
DADDIU R1, R1, 24 | 用特例法: DSGTUI R3, R1, 32时,原代码会循环4次,软流水装入代码+循环主体+排空代码相当于循环展开了4次,所以DSGTUI R3, R1, 32时软流水的跳转指令不应跳转。 为保证DSGTUI R3, R1, 32时,软流水的跳转指令不跳转,应在装入代码里改变R1的值让第一次跳转指令判断时R1的值为32。 由于下面的DADDIU指令会+8且影响跳转指令判断,为保证第一次跳转指令判断时R1的值为32,应+24。 这条指令下面R1的下标值统统-24,以保证下标正确 |
|||||||
DADDIU R2, R2, 24 | R2偏移多少不影响循环次数和正确性,可以为任意偏移值,所以本题答案不唯一 | |||||||
b: SDC1 F6, -24(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, -8(R2) | ||||||||
LDC1 F2, 0(R1) | ||||||||
DADDIU R1, R1, 8 | ||||||||
DSGTUI R3, R1, 800 | ||||||||
BEQZ R3, b | ||||||||
DADDIU R2, R2, 8 | 将R2自增的指令放到延迟槽里既不会影响循环次数,也不会影响循环顺序正确性 | |||||||
SDC1 F6, -24(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, -16(R2) | ||||||||
MUL.D F4, F2, F0 | ||||||||
LDC1 F8, -8(R2) | ||||||||
ADD.D F6, F4, F8 | ||||||||
SDC1 F6, -8(R2) | ||||||||
软件流水题目解题步骤 | ||||||||
1.
展开对齐,展开次数为原循环主体RAW相关的次数加1,没有RAW相关的语句可以合并为一句 2. 根据展开对齐后的代码写出装入代码+软流水循环主体代码+排空代码 3. 加入原循环中除主体循环以外的指令并调整下标 4. 在装入代码中加入语句保证指令顺序和数量与原循环一致,用特例法得到偏移值,并调整下标 |
||||||||