2013-11-25 35 views
2

this answer某人寫入爲什麼流水作業對於(a + b)+(c + d)比對a + b + c + d更好?

[..]大多數編譯器不會優化+ B + C + d以(A + B)+(C + d)(這是因爲第二個表達式的優化可以更好地進行流水線式)

原來的問題是如何某些涉及float值表達式可以或不可以被重新排序由於浮點運算的不精確性。

我更感興趣的是上面的一部分,儘管:爲什麼 - 比方說,有unsigned int值 - 這將是更容易生成代碼,如果a+b+c+d改寫爲(a+b)+(c+d)它利用CPU的管道?

回答

3

a + b和c + d可以並行計算。

像這樣:

x = a+b 
y = c+d 
return x+y // requires x and y 

VS

x = a+b 
y = x+c // requires x 
return y+d // requires y (and thus x) 

當計算y一個必須等​​待的x結果先來了,他們之間有一個數據的依賴。請參閱維基百科上的Instruction-level parallelism

+0

+1爲解釋和維基百科鏈接! –

2

With unsigned int?它不會。 Integer操作可以自由地重新排序而沒有任何影響結果的風險,所以任何半面體編譯器都應該爲這兩個表達式生成相同的代碼,因爲它們在討論浮動時只是意味着不同。

+0

除C指定二進制「+」運算符的從左到右的關聯性外,編譯器不能自由地對操作進行重新排序。 (參見例如[C和C++中的運算符](http://en.wikipedia.org/wiki/Operators_in_C_and_C++)。)編譯器必須編譯'a + b + c + d',就好像它被寫入'(( a + b)+ c)+ d' –

+4

當存在潛在的副作用或操作未完全關聯(如在浮點算法中)時,這隻會限制編譯器的自由度。編譯器總是可以自由地重新排序,而不會影響結果。 – user57368

+1

無符號整數運算可以自由地重新排序(取決於相應的數學運算),因爲它們使用模運算。除非C實現保證超出C標準要求(可能會),否則有符號整數操作不能自由地重新排序。例如,用'int','a +(b + c)'可能在'a + b + c'不會溢出時溢出。 –

2

如果你的編譯器生成的中間SSA,它可能會出來找這樣的:

AB = a + b; 
ABC = AB + c; 
ABCD = ABC + d; 
在第一種情況下

,並:

AB = a + b; 
CD = c + d; 
ABCD = AB + CD; 

在案例1中,每個術語包括上一屆,所以即使ALU能夠一次添加多個項,也必須等待前一個操作的結果才能開始下一個。在情況二中,像現代x86這樣具有多個ALU管線的處理器可以獨立同時計算ABCD

+0

+1 - 識別和利用這種並行性使得編譯器的x86代碼生成部分的工作人員完成的工作更加令人印象深刻。 –

相關問題