1.選擇合適的演算法和資料結構。
2.編寫出編譯器能夠有效優化以轉換為高效可執行的源**。
3.平行計算。
當然重點還是第乙個,良好的演算法和資料結構大大減小了程式的時間複雜度。
編譯器可以對程式進行不同程式的優化,在終端中,編譯時新增命令列選項-o1,-o2等等可以進行不同級別的優化,這樣雖然提高了程式的效能,但是也加大了程式的規模。
首先要進行安全的優化,在這個例子中:
1void twiddle1(int *xp,int *yp)26
void twiddle2(int *xp,int *yp)
7
編譯器是不會將twiddle1優化成twiddle2的,雖然twiddle2只需要三次訪問記憶體,而twiddle1需要6次。編譯器需要考慮xp和yp相等的情況,這樣兩個函式的結果就會不同,兩個指標可能只
想同乙個儲存器位置的情況成為儲存器別名使用。第二個妨礙優化的因素是函式呼叫,f()+f()+f()+f()和4*f()總會有點區別的,因為執行一次f()有可能就修改了全域性變數的值,在下次呼叫時
環境就可能不同,屬於函式的***。
考慮利用處理器的微體結構的優化,完成一些基本的優化。
1.整體操作(icu,eu)。
2.分支**:現代處理器中採用了分支**的技術,處理器在執行某條指令序列時會**下一條指令的位置,是否選擇分支,**分支的目標位址,投機執行,如果**錯誤,將狀態重新設定到分支點的狀態。
3.功能單元的特性:延遲,運算所需要的總時間;發射時間,兩個連續的同型別運算之間需要的最小時鐘週期數。
4.關鍵路徑:這是執行一組機器指令所需要時鐘週期數的乙個下界,迴圈運算中,有些資料是不能同時並行運算的,他們必須乙個接乙個的運算,因為後一次運算依賴於前一次
計算的結果。所以該計算流程就是該迴圈中的關節資料流。該資料流處理的必須用時,就成為了優化的界限。
每元素的週期數,cycles per element 來表示程式的效能。
1.**移動。比如將迴圈中計算結果不會改變的計算移出,減少計算。
2.減少過程的呼叫。
3.消除不必要的儲存器引用。減少對儲存器的訪問,比如 *dest=*dest*a[i]中,每次迴圈都要進行一次儲存器的訪存。可通過先賦值給乙個區域性變數,最後再賦值給*dest。
4.迴圈展開。通過增加每次迭代的計算的元素的數量,減少迴圈的迭代次數。展開的次數越高,cpe 效能越接近1。他減少了不直接有助於程式結果的操作的數量,比如迴圈索引的計算和條件分支,其次減少了整個計算中關鍵路徑上的運算元量。
5.提高並行性。多個積累變數,通過多個變數計算最後再合併以提高程式效能。重新結合變換,對於乙個計算表示式中,兩個連乘,我們可以使用括號,讓後一次乘法先進行,然後再進行前一次乘法。這樣做的能提公升程式速度的原理在於,如果使用順序乘法,第一次乘法結果與第二次乘法結果都會儲存在同乙個暫存器中,無形中增長了關鍵路徑。通過該優化方法,能使得關鍵路徑變短。
其實說這麼多,最好的還是選擇個合適資料結構和演算法來實現程式的優化,對於大資料,可能需要的這些優化措施多一些。
優化程式效能(CSAPP)
一 程式優化綜述 1 高效程式的特點 1 適當的演算法和資料結構。方法和資料的組織形式無疑是最關鍵的,是優化的基礎 2 能夠被編譯器轉化成高效的可執行 需要深入了解使用的編譯器的優化方法,和常見的優化策略 3 運用現代並行程式設計技術。多核以及硬體支援提供更大的加速可能,例如gpu 2 優化程式的一...
CSAPP 優化程式效能 二
程式示例 為了說明乙個抽象程式是如何被系統地轉換成更有效的 的,我們使用基於如下所示的向量資料結構的執行示例 向量由兩個記憶體塊表示,頭部和資料陣列,頭部宣告結構如下,data t代表基本資料型別 typedef struct vec rec,vec ptr 生成向量,訪問向量元素,確定向量長度的基...
讀CSAPP 2 程式效能優化
合適的資料結構與演算法 編寫出編譯器能夠有效優化以轉換成高效可執行 的原始碼。將運算量特別大的計算,可以分成多部分,這些部分可以在多核多處理器的某種組合上並行處理 本篇主要以第二點進行討論,編譯器在優化的時候只會做最壞打算,做各種假設。為了保證程式的準確性,捨棄效能優化。void twiddle1 ...