i++循環(huán)與i-–循環(huán)的執(zhí)行效率(遞增與遞減效率)
更新時(shí)間:2011年01月05日 23:44:05 作者:
i++循環(huán)與i-–循環(huán)的執(zhí)行效率(遞增與遞減效率),需要的朋友可以參考下。
昨天同事問(wèn)了我一個(gè)問(wèn)題,有兩個(gè)循環(huán)語(yǔ)句:
for(i = n; i > 0; i--)
{
…
}
for(i = 0; i < n; i++)
{
…
}
為什么前者比后者快?
我當(dāng)時(shí)的解釋是:
i- -操作本身會(huì)影響CPSR(當(dāng)前程序狀態(tài)寄存器),CPSR常見(jiàn)的標(biāo)志有N(結(jié)果為負(fù)), Z(結(jié)果為0),C(有進(jìn)位),O(有溢出)。i > 0,可以直接通過(guò)Z標(biāo)志判斷出來(lái)。
i++操作也會(huì)影響CPSR(當(dāng)前程序狀態(tài)寄存器),但只影響O(有溢出)標(biāo)志,這對(duì)于i < n的判斷沒(méi)有任何幫助。所以還需要一條額外的比較指令,也就是說(shuō)每個(gè)循環(huán)要多執(zhí)行一條指令。
(這是五年前tjww告訴我的,當(dāng)時(shí)他在AVR上寫(xiě)一個(gè)LCD驅(qū)動(dòng)程序,使用后者LCD會(huì)閃爍,使用前者則沒(méi)有問(wèn)題。)
為了確認(rèn)我的理解是正確的,做了個(gè)實(shí)驗(yàn):
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--的循環(huán)條件:
4c: e51b3014 ldr r3, [fp, #-20]
50: e3530000 cmp r3, #0 ; 0x0
54: cafffff5 bgt 30 <loop_dec+0x30>
i++的循環(huán)條件:
b8: e51b3018 ldr r3, [fp, #-24]
bc: e1520003 cmp r2, r3
c0: bafffff4 blt 98 <loop_inc+0x30>結(jié)果和我想象的并不一樣,這是怎么回事呢?我想可能因?yàn)闆](méi)有加優(yōu)化選項(xiàng),于是加上-O選項(xiàng),結(jié)果變?yōu)椋?
i--的循環(huán)條件:
14: e2500001 subs r0, r0, #1 ; 0x1
18: 1afffffc bne 10 <loop_dec+0x10>
i++的循環(huán)條件:
3c: e2833001 add r3, r3, #1 ; 0x1
40: e1500003 cmp r0, r3
44: 1afffffb bne 38 <loop_inc+0x14>這下沒(méi)錯(cuò)了,果然少一個(gè)cmp指令。
文章出處:http://www.limodev.cn/blog
復(fù)制代碼 代碼如下:
for(i = n; i > 0; i--)
{
…
}
for(i = 0; i < n; i++)
{
…
}
為什么前者比后者快?
我當(dāng)時(shí)的解釋是:
i- -操作本身會(huì)影響CPSR(當(dāng)前程序狀態(tài)寄存器),CPSR常見(jiàn)的標(biāo)志有N(結(jié)果為負(fù)), Z(結(jié)果為0),C(有進(jìn)位),O(有溢出)。i > 0,可以直接通過(guò)Z標(biāo)志判斷出來(lái)。
i++操作也會(huì)影響CPSR(當(dāng)前程序狀態(tài)寄存器),但只影響O(有溢出)標(biāo)志,這對(duì)于i < n的判斷沒(méi)有任何幫助。所以還需要一條額外的比較指令,也就是說(shuō)每個(gè)循環(huán)要多執(zhí)行一條指令。
(這是五年前tjww告訴我的,當(dāng)時(shí)他在AVR上寫(xiě)一個(gè)LCD驅(qū)動(dòng)程序,使用后者LCD會(huì)閃爍,使用前者則沒(méi)有問(wèn)題。)
為了確認(rèn)我的理解是正確的,做了個(gè)實(shí)驗(yàn):
復(fù)制代碼 代碼如下:
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--的循環(huán)條件:
4c: e51b3014 ldr r3, [fp, #-20]
50: e3530000 cmp r3, #0 ; 0x0
54: cafffff5 bgt 30 <loop_dec+0x30>
i++的循環(huán)條件:
b8: e51b3018 ldr r3, [fp, #-24]
bc: e1520003 cmp r2, r3
c0: bafffff4 blt 98 <loop_inc+0x30>結(jié)果和我想象的并不一樣,這是怎么回事呢?我想可能因?yàn)闆](méi)有加優(yōu)化選項(xiàng),于是加上-O選項(xiàng),結(jié)果變?yōu)椋?
i--的循環(huán)條件:
14: e2500001 subs r0, r0, #1 ; 0x1
18: 1afffffc bne 10 <loop_dec+0x10>
i++的循環(huán)條件:
3c: e2833001 add r3, r3, #1 ; 0x1
40: e1500003 cmp r0, r3
44: 1afffffb bne 38 <loop_inc+0x14>這下沒(méi)錯(cuò)了,果然少一個(gè)cmp指令。
文章出處:http://www.limodev.cn/blog
相關(guān)文章
如何使用VSCode插件Remote-Tunnels連接服務(wù)器
本文介紹使用Remote?-?Tunnels連接服務(wù)器,該方法需要遠(yuǎn)程服務(wù)器有流暢的網(wǎng)絡(luò)環(huán)境,它使用微軟的服務(wù)來(lái)建立隧道,需要登錄GitHub,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11風(fēng)中葉老師講述的學(xué)習(xí)方法(學(xué)習(xí)編程的朋友需要看)
風(fēng)中葉老師講述的學(xué)習(xí)方法(學(xué)習(xí)編程的朋友需要看),希望大家能按照說(shuō)明的那樣,自己多動(dòng)手動(dòng)腦2008-10-10vs2019生成dll并調(diào)用的實(shí)現(xiàn)示例
這篇文章主要介紹了vs2019生成dll并調(diào)用的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02tcp、udp、ip協(xié)議分析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了tcp、udp、ip協(xié)議分析的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07