2011-02-08 255 views
4

從有效的C++斯科特邁爾斯:編譯器優化「常量傳播」是什麼意思?

template<typename T, std::size_t n> 
class SquareMatrix: private SquareMatrixBase<T> { 

public: 

    SquareMatrix() 
    : SquareMatrixBase<T>(n, 0), 
     pData(new T[n*n]) 
    { 
     this->setDataPtr(pData.get()); 
    } 

     ... 
private: 

    boost::scoped_array<T> pData; 
}; 

無論數據被存儲 其中,從膨脹 角度來看關鍵結果是,現在許多 - 說不定 所有 - 方陣的構件 的函數可以是簡單的內聯調用 到共享的基類版本 與所有其他矩陣保持相同類型的數據,無論它們的大小爲 。與此同時,方陣 不同大小的對象是 不同的類型,因此,即使,例如, 方陣<雙,5>和 方陣<雙,1 0>對象使用 在 同一成員函數SquareMatrixBase <雙>,沒有 通過 SquareMatrix < double,5>對象到 函數期望的機會 SquareMatrix < double,10>。很好,不是嗎?

不錯,是的,但不是免費的。與基質轉化的 尺寸 硬連線到他們的版本是可能 產生比共享 版本,其中尺寸爲 函數參數傳遞或存儲在 對象更好的代碼。例如,在特定 尺寸版本,大小 將編譯時間常數,因此 享有這樣的優化如 常數傳播,包括它們的 被摺疊到產生 指令作爲立即操作數。 這不能在 大小無關的版本中完成。

在最後一段上面的描述中也提及爲「因此享有這樣的優化恆定傳播,包括它們被摺疊到 生成的指令作爲立即操作數」。這個說法是什麼意思?請求解釋這一點。

謝謝!

+2

http://en.wikipedia.org/wiki/Constant_propagation – 2011-02-08 15:31:09

回答

8

常量傳播是一個非常簡單的(原則上)優化留給編譯器。

size_t radius = 5; 
size_t diameter = 2*radius; 
float perimeter = diameter * 3.1416f; 

這將是由編譯器減小通過傳播常數:

  • 通知說的radius值是已知
  • 執行的2*radius計算(這是恆定的摺疊)
  • 因此diameter的值是已知的
  • 執行計算diameter * 3.1416f
  • 因此的perimeter值是已知的

該方案是這樣等同於:

size_t radius = 5; 
size_t diameter = 10; 
float perimeter = 31.416f; 

注意,還有很多其他形式的優化的,例如,如果radiusdiameter現在沒有需要更長時間,我們可以刪除它們,只保留perimeter

0

如果你有原來的代碼,如:

b==7; 
a==10; 

這就是所謂的常量傳送和常量摺疊:

a:=3; 
b:=4; 
b+=1; 
b+=2; 
a:=a+b; 

那麼語句可以通過編譯器優化的。