i++,i--執行效率

轉載時請註明出處和作者聯繫方式
文章出處:http://www.limodev.cn/blog
作者聯繫方式:李先靜 <xianjimli at hotmail dot com>

昨天同事問了我一個問題,有兩個循環語句:

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 < n的判斷沒有任何幫助。所以還需要一條額外的比較指令,也就是說每個循環要多執行一條指令。

(這是五年前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
c0: bafffff4 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: 1afffffb bne 38

這下沒錯了,果然少一個cmp指令。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章