2013-04-07 24 views
0

假設我們有下面的代碼:C++編譯器是否將多個算法組合到一個循環中?

int main() { 
int myints[] = {3,7,2,5,6,4,9}; 

// using default comparison: 
std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n'; 
std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n'; 
} 

將編譯器優化上面爲一個循環?還是寫一個for循環更好?

+0

這聽起來像是一個微觀優化問題...... – 2013-04-07 11:48:52

+1

沒有* C++編譯器這樣的東西。有你的C++編譯器,還有我的C++編譯器。你的可能不會優化和挖掘。告訴編譯器的唯一方法是檢查編譯器生成的代碼。我同意奧利的觀點,你應該擔心除此之外的其他事情。 – john 2013-04-07 11:50:30

+0

可能它可以。理論上,它也可以用向量化版本的指令來代替這兩個調用,所以「for」循環看起來會非常不同。如果一個循環對你很重要,你應該自己寫。 – dasblinkenlight 2013-04-07 11:56:42

回答

1

答案就像在許多事情中,這取決於。

如果編譯器決定將循環融合在一起,因爲它可以基於啓發式提高運行時性能。

沒有更合理,因爲只有7個元素和loop-fusion是沒有意義的。

還要注意,融合沒有意義,因爲操作只執行一次(在該示例中)。


爲了獲得更詳細的解答一下你的編譯器裝配輸出和比較不同的編譯器的輸出。


另一件事是,爲什麼要關心這樣的微觀優化,如果它不提高性能。

+0

感謝您的回覆!我實際上有更大的向量,12個單獨的std :: transform與lambda函數在c + + 11。 – user2254391 2013-04-07 12:26:39

+0

我是downvoting,因爲你的答案是這樣的:「如果編譯器做了循環融合,編譯器會循環融合,而且它也可能不......也不會微調優化。」這聽起來很像是一種輕視的同義反復,而不是一個明智的答案。 – Veedrac 2015-12-24 14:12:48

+0

@Veedrac應該列出所有可能的當前和未來編譯器與所有標誌...確定答案不明確,但它可以被定義爲「取決於編譯器和設置可能的優化」 – Quonux 2015-12-26 19:03:53

3

這取決於編譯器。例如,我的編譯器(g++ 4.7.3x86_64)沒有,保持兩個獨立的迴路(與-O3編譯時):

_main: 
;=== initialization code omitted === 
     jmp  L2 
L3: 
     movl (%rax), %edx 
     cmpl %edx, %ebx 
     cmovg %edx, %ebx 
L2: 
     addq $4, %rax 
     cmpq %rbp, %rax 
     jne  L3 
;=== output code omitted === 
     jmp  L8 
L6: 
     movl (%rax), %ecx 
     cmpl %ecx, (%rdx) 
     cmovl %rax, %rdx 
L8: 
     addq $4, %rax 
     cmpq %rbp, %rax 
     jne  L6 
;=== output code omitted === 
3

優化是,通過定義,而不是由標準規定的,因此它實際上取決於編譯器...和其他條件的提升。

在你的特殊情況下,我想表示std::minmax_element ......可能會派上用場。

+0

我是因爲標準的迂腐行爲≠編譯器,雖然正確和有用,但它不過是對實際問題的附帶評論。對於你的第二點評論來說,這一點非常重要。 – Veedrac 2015-12-24 14:10:16

相關問題