天天看點

《高性能科學與工程計算》——2.2 優化常識

本節書摘來自華章計算機《高性能科學與工程計算》一書中的第2章,第2.2節,作者:(德)georg hager gerhard wellein 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

簡單的代碼修改經常會帶來性能的顯著提升。下面的章節總結了避免性能缺陷的幾個最重要的“優化常識”。這些方法看似微不足道,但許多科學應用程式在應用這些方法後,性能都有了顯著提升。

2.2.1 少做工作

重新組織代碼以減少代碼工作量,在很多情況下可顯著提升性能。最常見的例子是循環檢測一組對象是否具有特定屬性,任一對象具備該屬性即可:

《高性能科學與工程計算》——2.2 優化常識

如果complex_func()函數沒有其他作用,flag是唯一和循環外部通信的變量。這種情況下,flag值一經改變,就立即退出循環可明顯減少計算工作量(取決于條件判斷變為true的機率):

《高性能科學與工程計算》——2.2 優化常識

https://yqfile.alicdn.com/b7d273e971274bde46269576ca7d51640b7cc023.png

" >

2.2.2 避免耗時運算

算法的實作通常采用“步步為營”的政策。首先不做性能方面(因為在進行性能優化時,往往存在更改數值運算的風險)的考慮,将公式直接翻譯成代碼。第二步使用“便宜”運算替代“昂貴”運算。三角函數和幂運算是“強”運算(“昂貴”運算)的典型代表。記住類似x*2.0的表達式是不會被編譯器優化成xx的,而指數(對數)的運算性能是很低的。避免“昂貴”運算的優化方法稱為強度消減(strength reduction)。除上述簡單情況外,“強”運算有時會關聯一組有限的固定參數。下面是一個非平衡自旋系統仿真代碼的例子:

《高性能科學與工程計算》——2.2 優化常識

程式的最後兩行代碼包含在一個循環中,并占用該應用程式幾乎全部的運作時間。整型變量用于存儲自旋取向(向上或者向下,對應值為1或者-1),是以變量edelz的取值範圍為{-6,…,+6}。在整個應用程式中,tanh()函數即便用硬體實作也是最耗時的操作(至少幾十個時鐘周期)。根據以上描述,可根據參數範圍将該函數結果轉存在一個數組中,循環内部完全消除對tanh()函數的調用。假設tt為定值,那麼這個表格隻需建立一次:

《高性能科學與工程計算》——2.2 優化常識

https://yqfile.alicdn.com/3f76ed1878eb497ec08fa747a0e19cea569a20e9.png" >

這個數組存儲在訪存性能非常高的l1 cache中。是以,相對于tanh()函數,該數組的查找時間可以忽略不計。由于該數組尺寸較小且被頻繁調用,是以整個計算過程都會被存儲在l1 cache中。

2.2.3 縮減工作集

程式代碼在計算過程中或至少在整體運作時間中的記憶體使用量稱為該代碼的工作集。一般情況下,壓縮工作集會提高cache命中率,對性能提升有正面影響。如何實作工作集壓縮以及是否會帶來性能提升,很大程度上取決于算法和它的實作。上例中,原始代碼使用了4位元組的整除存儲自旋取向,工作集也是以遠遠大于所有處理器的l2 cache。如果改變數組定義,使用1位元組的整數來存儲自旋取向。工作集會是以減小将近4倍,進而接近cache大小。

然而,并不是所有處理器都能有效處理“小”資料類型。如果處理器采用較大的字長,單位元組類型資料通過移位和标記操作抽取,那麼使用單位元組整型資料的程式會非常低效。另一方面,如果可以采用simd指令,那麼采用簡單資料類型的程式就會非常高效(具體見2.3.3節)。

繼續閱讀