考慮下面的代碼段示出了一些簡單的算術運算gcc是否以代數方式優化C++代碼,如果是的話,程度如何?
int result = 0;
result = c * (a + b) + d * (a + b) + e;
要獲得的結果在CPU上方的表達將需要執行兩個整數乘法和三個整數加法。但是,代數上面的表達式可以簡化爲下面的代碼。
result = (c + d) * (a + b) + e
這兩個表達式在代數上是相同的,但第二個表達式只包含一個乘法和三個加法。 gcc(或其他編譯器)能夠自己做出這種簡單的優化。
現在假設編譯器足夠智能以進行此簡單優化,是否能夠優化更復雜的內容,如Trapezoidal rule(用於數值積分)。下面的示例近似sin(x)
下的區域,其中0 <= x <= pi
的步長爲pi/4(爲了簡單起見,小)。請假定所有文字都是運行時變量。
#include <math.h>
// Please assume all literals are runtime variables. Have done it this way to
// simplify the code.
double integral = 0.5 * ((sin(0) + sin(M_PI/4) * (M_PI/4 - 0) + (sin(M_PI/4) +
sin(M_PI/2)) * (M_PI/2 - M_PI/4) + (sin(M_PI/2) + sin(3 * M_PI/4)) *
(3 * M_PI/4 - M_PI/2) + (sin(3 * M_PI/4) + sin(M_PI)) * (M_PI - 3 * M_PI/4));
現在上面的函數可以這樣寫,就像使用梯形法則一樣簡化了。這大大減少了獲得相同答案所需的乘法/除法的次數。
integral = 0.5 * (1/no_steps /* 4 in th case above*/) *
(M_PI - 0 /* Upper and lower limit*/) * (sin(0) + 2 * (sin(M_PI/4) +
sin(3 * M_PI/4)) + sin(M_PI));
請提供指向C/C++語言規範的鏈接。在此之前,只有兩種不同的**語言C和C++。選一個!你的問題對於SO來說太廣泛了。請自己做一些研究。 gcc郵件列表可能是一個好的開始。或者你只是閱讀源代碼。 – Olaf
您可以隨時編譯並檢查程序集以查看它的功能。 – NathanOliver
小心!當你開始考慮整數溢出時,這種代數重排通常會中斷。我無法想到這個特定表達式的反例,但有很多表達式會打破它。 –