2012-01-23 81 views

回答

17

第二個「可能」會更好,因爲將i與0比較比將i與10比較更容易,但我認爲您可以使用其中的任何一個,因爲編譯器會優化它們。

+0

爲什麼比較'i'與0比10更容易? –

+1

+1削減新手一些鬆懈,因爲他的答案是在正確的線 –

+10

因爲大多數處理器有指令比較零?所以他們不需要加載'i'和10,減去他們,然後比較爲零,但只是立即比較'i'爲零。 – user1023979

1

編譯器應該優化兩個代碼到同一個程序集,所以它沒有什麼區別。兩者都採取同一時間。

更有效的討論將是

for(int i=0;i<10;++i) //preincrement 
    { 
    } 

是否會快於

for(int i=0;i<10;i++) //postincrement 
    { 
    } 

因爲,從理論上說,後加做額外的操作(返回參照舊值)。但是,即使這樣,也應該對同一個組件進行優化。

沒有優化,代碼應該是這樣的:

for (int i = 0; i < 10 ; i++) 
0041165E mov   dword ptr [i],0 
00411665 jmp   wmain+30h (411670h) 
00411667 mov   eax,dword ptr [i] 
0041166A add   eax,1 
0041166D mov   dword ptr [i],eax 
00411670 cmp   dword ptr [i],0Ah 
00411674 jge   wmain+68h (4116A8h) 

    for (int i = 0; i < 10 ; ++i) 
004116A8 mov   dword ptr [i],0 
004116AF jmp   wmain+7Ah (4116BAh) 
004116B1 mov   eax,dword ptr [i] 
004116B4 add   eax,1 
004116B7 mov   dword ptr [i],eax 
004116BA cmp   dword ptr [i],0Ah 
004116BE jge   wmain+0B2h (4116F2h) 

    for (int i = 9; i >= 0 ; i--) 
004116F2 mov   dword ptr [i],9 
004116F9 jmp   wmain+0C4h (411704h) 
004116FB mov   eax,dword ptr [i] 
004116FE sub   eax,1 
00411701 mov   dword ptr [i],eax 
00411704 cmp   dword ptr [i],0 
00411708 jl   wmain+0FCh (41173Ch) 

所以即使在這種情況下,速度是一樣的。

+0

應該優化到相同的程序集......如果在循環內部使用「i」會怎麼樣? – Benoit

+0

@Benoit我的意思是相同數量的指令。 –

5

如果針對零的測試在硬件中進行優化,則遞減到零的循環有時會更快。但這是一個微型優化,你應該知道它是否值得做。編譯器通常會爲你做優化,並且鑑於遞減循環可能是一種更糟糕的意圖表達方式,你通常堅持採用'正常'方法會更好。

7

我做不是認爲兩個循環的性能差別很大。

我想,當循環看起來像這樣,它會變成不同的情況。

for(int i = 0; i < getMaximum(); i++) 
{ 
} 

for(int i = getMaximum() - 1; i >= 0; i--) 
{ 
} 

作爲getMaximum()函數被調用一次或多次(假定它不是一個內聯函數)

2

遞增和遞減(INC和DEC,當翻譯成彙編命令)具有1相同的速度CPU週期。

但是,第二個可以對一些(例如SPARC)架構理論上更快因爲沒有10必須從內存(或緩存)獲取:大多數架構與特compating時處理以優化的方式說明值0(通常有一個特殊的硬連線0寄存器用作操作數,所以沒有寄存器必須被「浪費」以存儲10用於每次迭代的比較)。

一個聰明的編譯器(尤其是如果目標指令集RISC)將自身檢測到並(如果你的計數器變量沒有在循環使用),應用第二「減量DOWNTO 0」的形式。

請參閱答案https://stackoverflow.com/a/2823164/1018783https://stackoverflow.com/a/2823095/1018783進一步的細節。

+0

說到一條指令的執行時間在超標量體系結構上沒有意義。桌面處理器在過去的15年中一直是超標量的(1993年的奔騰處理器是超標量的)。 – AProgrammer

+0

並非所有的現代硬件都是流水線的。嵌入式處理器與這種微型優化具有更多的相關性。此外,OP問題沒有針對現代臺式機處理器,所以我相信答案應該是通用的,並且地址也應該是20年前的處理器設計(通常仍然用作嵌入式CPU) –

+0

問題是,答案取決於它。這取決於處理器ISA是否有更好的支持。這取決於微架構是否能夠利用ISA支持。如果編譯器也能夠利用(並且不能採取對抗措施,例如將10保存在寄存器中,則可以看到循環被執行了已知的少量時間並且完全展開或者使用輔助遞減計數器) 。變數太多了。在上下文中衡量和衡量是唯一的答案,它對所有應用程序都有效。 – AProgrammer

0

同樣,回答所有的微性能問題是措施,測量使用的背景下不要外推到其他情境。

計數指令執行時間不是很長一段時間沒有一個極爲成熟成爲可能。

處理器和內存速度和引進緩存隱藏等待時間的部分之間的不匹配(但不是帶寬)使得一組指令到存儲器訪問模式非常敏感的執行。這是你仍然可以通過相當高層次的思考進行優化。但是,這也意味着,如果不考慮內存訪問模式,顯然更糟的是,一旦完成,就會更好。

然後超標量(處理器可以同時做幾件事情)和亂序執行(處理器可以在流中的前一個執行指令之前執行指令這一事實)使得基本計數無意義,即使忽略內存訪問。您必須知道哪些指令需要執行(因此忽略部分結構不明智)以及處理器如果想要獲得良好的先驗估計,可以如何分組指令。

相關問題