2011-05-13 43 views
9

快速的問題,事先假定相對業績加指令

mov eax, 0 

這是更有效?

inc eax 
inc eax 

add eax, 2 

此外,在情況下,兩個inc s爲更快,做編譯器(就是說,GCC)通常(即,W/O積極的優化標誌)優化var += 2呢?

謝謝你的時間! PS:不要用「不過早優化」的變體來回答,這只是學術上的興趣。

+4

答案可能是特定於處理器的,在大多數情況下,很可能沒有可測量的差異。如果您真的*有興趣知道某個特定CPU的答案,然後對其進行基準測試。 – 2011-05-13 14:32:42

+0

可能重複[ADD 1真的比INC快嗎? x86](http://stackoverflow.com/questions/13383407/is-add-1-really-faster-than-inc-x86) – 2017-05-21 10:26:01

回答

2

出於所有目的,它可能沒有關係。但考慮到公司使用較少的字節。

考慮下面的代碼:

int x = 0; 
x += 2; 

不使用任何優化的標誌,GCC編譯此代碼爲:

80483ed:  c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) 
80483f4:  00 
80483f5:  83 44 24 1c 02   addl $0x2,0x1c(%esp) 

使用-O1-O2,就變成:

c7 44 24 08 02 00 00 movl $0x2,0x8(%esp) 

有趣,不是嗎?

12

如果您想知道raw x86指令的性能統計信息,請參閱Dr Agner Fogs listings(第4卷精確)。至於關於編譯器的部分,那依賴於編譯器的代碼生成器,而不是你應該依賴太多的東西。

在一個側面說明

:我覺得很有趣/諷刺的是,在對性能問題,你用MOV EAX,0零寄存器,而不是XOR EAX,EAX:P(如果MOV EAX,0是事先完成,最快的變異會刪除公司的和添加的,只是MOV EAX,2)。

+0

+1爲Agner霧;-) – hirschhornsalz 2012-11-15 00:22:13

17

在同一個寄存器(或者更一般地說是兩個讀 - 修改 - 寫指令)上的兩條指令總是有一個至少有兩個週期的依賴鏈。這是假設一個公司的一個時鐘等待時間,這是自486以來的情況。這意味着如果周圍的指令不能與兩個inc指令交錯來隱藏這些等待時間,則代碼將會執行得更慢。

但是,沒有編譯器會發出你提出反正指令序列(mov eax,0xor eax,eax被替換,見What is the purpose of XORing a register with itself?

mov eax,0 
inc eax 
inc eax 

將optimizied到

mov eax,2 
+1

請注意'xor eax,eax;儘管如此,inc eax'比大多數編譯器的'mov eax,1'更受青睞。可能是因爲它是3字節而不是5。 – Polynomial 2013-08-15 22:27:00

+0

@Polynomial如果'mov eax,0'可以用2個字節編碼,那麼'mov eax,1'也可以用2個字節編碼(1個操作碼+ 1個立即數) – 2014-05-26 13:56:33

+0

@LưuVĩnhPhúc'mov eax,1'爲5個字節:'b8 01 00 00 00'。由於8字節的文字和QWORD前綴:'48 b8 01 00 00 00 00 00 00 00',因此64位是10個字節。比較而言,'xor rax,rax; inc eax'只有5個字節:'48 31 c0 ff c0' – Polynomial 2014-05-26 22:27:00

2

從英特爾的手冊,你可以找到here它看起來像ADD/SUB指令在一個特定的架構上便宜了半個週期。但請記住,英特爾對其最新處理器使用無序執行模式。這主要意味着,無論處理器何時需要等待數據進入(例如,在L1/L2/L3/RAM數據獲取期間耗盡事物),都會出現性能瓶頸。所以如果你是個人檔案,告訴你INC可能是問題;從數據吞吐的角度來看它,而不是看着原始的週期數。

Instruction    Latency1   Throughput   Execution Unit 
                  2 
CPUID     0F_3H 0F_2H  0F_3H 0F_2H 0F_2H 

ADD/SUB     1  0.5  0.5  0.5  ALU 
[...] 
DEC/INC     1  1   0.5  0.5  ALU 
+3

IIRC 0f_2h是P4普雷斯科特,他可以安息。這些半時鐘延遲是由內部雙時鐘管道產生的。對英特爾來說,這是一個非常糟糕的主意。 – hirschhornsalz 2011-05-13 15:06:03