下面我尝试使用bne循环100次,但我想修改代码以便它运行得更快。也许以某种方式删除nop?我该如何改进这段代码?
addi $1, $0, 100
addi $2, $0, 0
lw $3, 0($4)
add $2, $2, $3
addi $4, $4, 4
addi $1, $1, -1
bne $1, $0, -5
nop
答案 0 :(得分:5)
您可以做的第一件事就是使用分支延迟槽。 nop在每个循环中执行但没有完成任何操作。为什么不把那些增加4美元的指令放在那里(因为你不需要它来进行循环计算)?
跑得更快的第二步是查看相关指令。例如,将$ 3添加到$ 2必须等到lw
完成,这可能需要几个机器周期。从$ 1减1不需要等待任何事情。如果颠倒这两条指令的顺序,则可以在负载仍在进行时进行减法,而不是等待它完成(这取决于体系结构,可能不会出现在所有系统上,特别是在模拟器上)。
第三步是重新构建循环。您正在递增指针($ 4)并在每个循环上递减循环计数器($ 1)。为什么不结合它们?你知道开始时4美元是什么,你知道最后会有4美元(4美元+(4 * 100))。所以你可以增加4美元,看它是否到了最后。这应该为每个循环保存一条指令。
答案 1 :(得分:1)
您的代码:(已优化)
addi $1, $0, 100
1: addi $2, $0, 0 #can replace with mov $2,$0 (easier to understand)
lw $3, 0($4) #don't need an offset, replace with lw $3,($4)
add $2, $2, $3
addi $4, $4, 4
bne $1, $0, 1b
addi $1, $1, -1
我删除了nop并交换了bne和addi指令,以便cpu不会浪费任何周期。 addi总是在分支延迟槽中执行。
PS可变长度编码器提到add指令必须等待lw并且他是部分正确且部分不正确。如果体系结构支持转发,那么您不必等待(停止),就像MIPS体系结构的某些实现一样。但是,如果架构不支持转发(不太可能),则您必须执行他/她建议的操作,或者在lw之后交换两个添加指令