2015-02-10 35 views
1

我偶然發現了兩個等價增量語法之間的奇怪的持續時間差異。C++ - 有和沒有if語句的奇怪時間測量

if(seed != state) ++i; 

這個符號測量每個迭代1048576

i += (seed != state); 

2.25毫秒,每1048576次迭代這個2.80毫秒。

不應該第二個符號比第一個符號快一點? 這是要提到的是,種子==狀態很少發生(在2^32-1次之一)。

感謝您的回答。

編輯: 我用gcc C編譯器測試了同樣的東西,其中第一個比第二個稍快,但第二個與C++編譯器的速度相同。

+0

您是否使用優化版本進行了測量?那將是令人驚訝的。 – 2015-02-10 22:40:53

+0

這是沒有足夠的時間在操作系統下進行可靠的測量。運行幾次,你可能會得到不同的結果。讓它以十億次迭代運行,差異可能會消失。如果沒有,你如何編譯這個?具體而言,是否進行優化?我希望優化編譯器能夠爲此生成完全相同的代碼,但可能並非沒有優化。 – Wintermute 2015-02-10 22:40:59

+0

它以10億次迭代運行,但結果除以1000以獲得100萬次運行的平均值。即使使用-O3,第一個也會慢一點。 – bakkaa 2015-02-10 22:59:13

回答

0

使用if語句,編譯器可以將增量轉換爲條件執行語句(至少使用支持有條件執行的語句的處理器)。

第二個例子將總是執行1或0的加法。

這是微觀優化,真正取決於處理器及其支持系統(緩存,分支預測等)。例如,第二個示例可能會更快,因爲沒有決策跳轉。第一個例子可能在具有分支預測的處理器上更快。在可以將代碼片段放入指令緩存的處理器中,兩者之間的差異可以忽略不計(並且不需要獲取其他指令)。

我很驚訝,代碼執行是以毫秒爲單位。對於這些示例,大多數現代處理器應該在納秒內執行。

+0

我將nano轉換爲milli只是爲了好玩。 – bakkaa 2015-02-11 00:10:07

+0

@bakkaa:真的,你應該因爲提供錯誤的事實而失望「爲了好玩」。例如,我想知道你可能使用了哪種CPU架構,並得出結論,它必須是一些古老的微控制器,時鐘頻率低於1MHz,因爲它需要*毫秒*來計算。 – 2015-02-11 08:31:17

+0

@MarcusMüller:我沒有提供錯誤的事實。你應該被低估不聽。我說我把它從納米轉換爲毫米,但時間是一樣的。 1百萬納秒是1毫秒。你應該知道這一點。 – bakkaa 2015-02-11 15:29:25

3

if版本引發條件分支指令。另一個只是將一個bool轉換爲int並添加它。

編輯:

我會傾向使用由於技術上的轉化(int)true不需要由標準以導致1的第一個,;只需要導致「不爲零」。雖然在實踐中,我從來沒有見過boolint的轉換,但沒有使用1作爲true

+1

」...並*無條件*添加它。「 – WhozCraig 2015-02-10 22:40:42

+0

是的,謝謝。 – iwolf 2015-02-10 22:41:07

+0

它不會僅在2^32-1個案例中添加1個。 – bakkaa 2015-02-10 22:50:18

2

你永遠不知道你的編譯器如何優化你的代碼。分支預測實際上會使第一個更快。第二個取決於實際進行的比較,如果結果爲i,則結果爲1(這取決於您的CPU,但很可能會引入)「虛擬」1加載寄存器。

+0

由於你在托馬斯馬修斯的回答下的評論,你似乎誤解了我的馬庫斯穆勒。請考慮再讀一遍。 – bakkaa 2015-02-11 15:44:16

0

第一個可能有條件地不作爲分支預測的結果執行添加。第二個將添加每個週期,因爲沒有選項可以跳過添加。比較的結果將始終添加到i。

我會假設你會發現第一個不執行添加每個循環,但只是偶爾當分支預測失敗。

+0

添加不是僅在2^32-1個案例中的1箇中執行 – bakkaa 2015-02-10 23:13:00