【发布时间】:2015-02-03 15:22:55
【问题描述】:
我想知道为什么ARM指令默认不设置CPSR(如x86),但在这些情况下必须使用S位?当指令不改变 CPSR 提供更好的性能?例如,ADD 指令提供比 ADDS 更好的性能?或者真正的交易是什么?
【问题讨论】:
标签: arm
我想知道为什么ARM指令默认不设置CPSR(如x86),但在这些情况下必须使用S位?当指令不改变 CPSR 提供更好的性能?例如,ADD 指令提供比 ADDS 更好的性能?或者真正的交易是什么?
【问题讨论】:
标签: arm
这是为了性能,或者可能是。如果您总是更改标志,那么您很难在多条指令上使用一个标志而没有一个会干扰您的管道的分支。
if(a==0)
{
b=b+1;
c=0;
}
else
{
b=0;
c=c+1;
}
传统上你必须用分支来实现它(伪代码不是真正的 asm)
cmp a,0
bne notzero
add b,b,1
mov c,0
b waszero
notzero:
mov b,0
add c,c,1
waszero:
所以无论如何你都会遭受一个分支
但有条件执行
cmp a,0
addeq b,b,1
moveq c,0
addne c,c,1
movne b,0
没有分支,您只需翻阅代码,现在唯一可行的方法是 1) 您可以选择根据标志有条件地执行每条指令,以及 2) 修改标志的指令可以选择不修改标志
根据处理器系列/架构, add 甚至 mov 会修改标志,因此您必须同时具有条件执行和不设置标志的选项。这就是为什么 arm 有一个加法和一个加法。
我认为他们用 64 位架构摆脱了所有这些,所以可能和它一样有趣和酷,可能它没有被使用得足够多或不值得,或者他们只需要这四个位来将所有/一些指令保持为 32 位。
【讨论】:
我想知道为什么ARM指令默认不设置CPSR(如x86),但在这些情况下必须使用S位?
这是一种选择,取决于上下文。额外的灵活性仅受程序员想象力的限制。
什么时候指令不改变 CPSR 提供更好的性能?例如,
ADD指令提供比ADDS更好的性能?
很可能永远不会注意1。即,对于大多数 ARM CPU 和指令而言,未设置 CPSR 的指令不会执行得更快(更少的时钟)。
或者真正的交易是什么?
考虑一些“C”代码,
int i, sum;
char *p = array; /* passed in */
for(i = 0, sum = 0; i < 10 ; i++)
sum += arrary[i];
return sum;
这可以翻译成,
mov r2, r0 ; get "array" to R2
mov r1, #10 ; counter (reverse direction)
mov r0, #0 ; sum = 0
1:
subs r1, #1 ; set conditions
add r0, [r2], #1 ; does not affect conditions.
bne 1b
bx lr
在这种情况下,循环体很简单。但是,如果循环中没有条件,那么编译器(或汇编程序程序员)可以将循环减量安排在他们喜欢的任何地方,并且仍然将条件设置为稍后进行测试。这对于更复杂的逻辑和 CPU 可能由于数据依赖性而停顿的情况更为重要。这对于条件执行也很重要。
可选的“S”更多是多条指令的特性,而不是一条指令。
注意 1: 总有人可以制造 ARM CPU 并做到这一点。您将不得不查看数据表。我不知道有哪个 CPU 需要更多时间来设置条件。
【讨论】: