假设c级整数j
保存在寄存器$t1
中,$s2
保存名为total
的c级整数,$s0
保存基址整数数组vArray
。
addi $t1, $0, $0
LOOP:
lw $s1, 0($s0)
add $s2, $s2, $s1
addi $s0, $s0, 4
addi $t1, $t1, 1
slti $t2, $t1, 100
bne $t2, $s0, LOOP
我的解决方案:
我想我已经找到了C代码,应该是:
for (j = 0; j < 100; j++) {
total = total + vArray[j];
}
然后问题问:重写循环以减少执行的MIPS指令的数量。
但是,我无法减少执行的MIP指令数量。对我来说,我认为MIPs指令已经基本完成了,我无法想出另一个不到七个执行步骤的解决方案。
在阅读了减量建议之后,我想出了这个,可能有点笨拙的逻辑。
addi $t1, $zero, 404
LOOP:
subi $t1, $t1, 4
add $s0, $s0, $t1
lw $t2, 0($s0)
add $s2, $s2, $t2
bne $t1, $zero, LOOP
答案 0 :(得分:1)
在最小化指令方面,这是我能做的最好的事情:
addi $t1, $s0, 400
LOOP:
lw $s1, 0($s0)
add $s2, $s2, $s1
addi $s0, $s0, 4
bne $s0, $t1, LOOP
答案 1 :(得分:0)
寄存器$ t1实际上不需要递增或检查。它用于知道你已经执行了100次,但是当$ s0增加了400时你也能想出来。
答案 2 :(得分:0)
也循环展开。即忘记整个循环增量的事情,只做100次添加和100次内存获取操作。
答案 3 :(得分:0)
如果你想要尽可能小的代码,我想这可能是这样的:
add $s2, $0, $0 ; initialize sum to 0
addi $t1, $s0, $400 ; compute pointer limit
LOOP: lw $s1, 0($s0) ; load one element
addi $s0, $s0, 4 ; point to next element
add $s2, $s2, $s1 ; cumulate result (away from lw to skip delay slot)
bne $t2, $t1, LOOP ; loop until pointer reaches limit
nop ; delay slot of the branch
基本上,您使用指针值作为循环退出条件,而不是计算单独寄存器中的迭代。
如果你想利用延迟槽:
add $s2, $0, $0 ; initialize sum to 0
addi $t1, $s0, $400 ; compute pointer limit
LOOP: lw $s1, 0($s0) ; load one element
addi $s0, $s0, 4 ; point to next element
bne $t2, $t1, LOOP ; loop until pointer reaches limit
add $s2, $s2, $s1 ; cumulate result (in delay slot)
循环展开:
add $s2, $0, $0 ; initialize sum to 0
addi $t1, $s0, $400 ; compute pointer limit
LOOP: lw $s1, 0($s0) ; load first element
addi $s0, $s0, 8 ; compute next block address
add $s2, $s2, $s1 ; cumulate first element
lw $s1, -4($s0) ; load second element
bne $t2, $t1, LOOP ; loop until pointer reaches limit
add $s2, $s2, $s1 ; cumulate second element
每次加载和累积现在需要3个周期,而上面的一步循环中只有4个。
没有必要进一步展开循环,因为你不能在少于3个指令周期(一个内存加载,一个延迟槽,一个累加)中执行加载和累加步骤。