i++サイクルとi-Cサイクルの実行効率(増加と減少効率)

1628 ワード

昨日同僚は私に質問しました.2つの循環文があります.
 
  
for(i = n; i > 0; i--)
{

}

for(i = 0; i < n; i++)
{

}

どうして前者は後者より速いのですか.
私の説明は
i---操作自体がCPSR(現在のプログラム状態レジスタ)に影響し、CPSRでよく見られるフラグはN(結果は負)、Z(結果は0)、C(キャリーあり)、O(オーバーフローあり)である.i>0は、Zフラグで直接判断できる.
i++操作はCPSR(現在のプログラムステータスレジスタ)にも影響しますが、O(オーバーフローあり)フラグのみに影響します.これはi△5年前にtjwwが教えてくれたのですが、当時AVRにLCDドライバを書いていて、後者を使うとLCDが点滅し、前者を使うと問題ありませんでした.
私の理解が正しいことを確認するために、実験をしました.
 
  
int loop_dec(int n)
{
int i = 0;
int v = 0;

for(i = n; i > 0; i--)
v +=i;

return v;
}

int loop_inc(int n)
{
int i = 0;
int v = 0;

for(i = 0; i < n; i++)
v +=i;

return v;
}

arm-linux-gccでコンパイルし、逆アセンブリします.
i---の循環条件:
4c: e51b3014 ldr r3, [fp, #-20]
50: e3530000 cmp r3, #0 ; 0x0
54: cafffff5 bgt 30
i++のサイクル条件:
b8: e51b3018 ldr r3, [fp, #-24]
bc: e1520003 cmp r2, r3
c 0:bafffff 4 blt 98の結果は私が想像していたのとは違いますが、これはどういうことですか?おそらく、最適化オプションが追加されていないので、-Oオプションを追加すると、次のようになると思います.
i---の循環条件:
14: e2500001 subs r0, r0, #1 ; 0x1
18: 1afffffc bne 10
i++のサイクル条件:
3c: e2833001 add r3, r3, #1 ; 0x1
40: e1500003 cmp r0, r3
44:1 affffffb bne 38これで間違いなく、やはりcmp命令が1つ足りない.
記事の出典:http://www.limodev.cn/blog