本節書摘來自華章出版社《多核與gpu程式設計:工具、方法及實踐》一書中的第1章,第1.4節, 作 者 multicore and gpu programming: an integrated approach[阿聯酋]傑拉西莫斯·巴拉斯(gerassimos barlas) 著,張雲泉 賈海鵬 李士剛 袁良 等譯, 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
發展多核硬體和開發多核軟體的目标是擷取更高性能,例如更短的執行時間、更大規模的問題和更大的資料集等。很明顯,這需要一個客觀的标準或者準則來評估這些努力的有效性。
最起碼,一個并行程式的執行時間應該要比其對應的串行程式的執行時間短(然而,并不是所有情況都這樣)。執行時間的縮短通常表述為加速比,可用如下公式表達:

(1-1)
其中,對于解決同一個問題執行個體,tseq是串行程式的執行時間,tpar是并行程式的執行
時間。
tseq和tpar都是時間,但它們并不總客觀。二者會受到如下因素影響:
程式員技術水準
編譯器(例如,gnu c++與intel c++)
編譯器開關(例如,優化選項關閉或者開啟)
作業系統
儲存輸入資料的檔案系統(例如,ext4、ntfs等)
運作時間(不同的工作負載、不同的網絡流量)
為了能夠讓測得得加速比更具有可信性,需要遵循如下條件。
1.串行程式和并行程式都必須在相同軟體和硬體平台以及類似條件下進行測試。
2.串行程式應該是目前最快的解決方案。
其中,第二個條件雖不明顯,但是它非常重要。并行算法和與之對應的串行算法完全不同。事實上,一個串行算法可能沒有對應的并行版本,甚至可能無法構造其并行本版。
第二個條件非常重要的原因是:實作并行程式所付出的努力(開發成本特别高),隻有在獲得收益時才有價值。
對于給定的處理器數目,并行程式能夠獲得的加速比依然嚴重依賴于輸入資料(本節随後将會對這些進行詳細說明)。正是由于這個原因,在測試并行程式相對于串行程式的加速比時,往往會大量測試相同大小的不同資料集,甚至會給出最大、最小、平均加速比。
然而,加速比隻是問題的一個方面。例如,當加速比大于1時,僅能告訴我們,并行程式可以更快地解決問題。然而,加速比不能反映解決問題的有效性(是否于使用的資源相對應)。是以,第二個性能名額就是效率。通常情況下,效率的定義如下:
(1-2)
其中,n為執行并行程式時所使用的cpu或者計算核心的數目。效率可以了解為,當并行程式執行時每個計算節點 的使用率。效率為100%意味着加速比為n,工作負載平均配置設定在n個處理器上,每個處理器的使用率為100%(在執行過程中,處理器沒有空閑)。當加速比為n時,可以說并行程式獲得了線性加速比。
但是,這僅僅是一個理想情況。當多個處理器共同協作完成一個任務時,處理器間會存在通信。這個通信或者通過消息傳遞進行,或者通過共享資源進行。這些通信将會占用cpu的執行時間,導緻加速比小于n。
圖1-9顯示了利用梯形規則算法計算函數定積分示例程式的加速比和效率。計算負載取決于進行計算的梯形數量。圖1-9對應的目标計算平台是i7 950四核cpu,計算結果是将程式運作10遍獲得的平均值。
這裡有個問題應該要引起讀者的注意:如果我們隻有一個四核cpu,如何測試和報告8個線程的加速比?
intel i7 950四核cpu支援一種稱為超線程的技術。超線程技術通過複制cpu硬體中的某些部分,允許一個cpu計算核心運作兩個軟體線程。這使得cpu好像具有兩個計算核心。但是,平均隻有30%的性能提升,這和理想中的2倍加速比差别較大。圖1-9顯示了這方面的性能結果。這主要是因為在給定的計算平台上,我們沒有8個實體核心來運作8個線程。
效率随線程數目的增多而降低,這是顯而易見的。盡管效率降低與特定應用程式相關,但是這在并行程式中是一種常見情況。這歸結于并行程式的通信開銷,當cpu或者計算核心間的通信增多時,這個開銷就會增大。
每一條曲線都對應着不同線程數目的結果(如圖例所示)。圖a中的理想加速比曲線說明了并行程式性能提升的退化,這是不斷增加的通信開銷導緻的必然結果
圖1-9有兩個目的:1)給出真實加速比曲線和效率曲線;2)提高正确實驗技術的重要性。性能測試應該針對真正的硬體資源,而不是超線程提供的虛拟資源。
圖1-9a中的理想加速比曲線是衡量并行程式實作優劣的工具。如前所述,這是性能上限,并不總能達到。
當然,也存在加速比大于n或者效率大于1的情形,這稱為超線性加速比。根據效率的定義,這好像是不可能的情況。然而,我們應當知道串行程式處理資料的方式和并行程式不同,兩者有不同的執行路徑。例如,如果一個程式的目标是在搜尋空間中查找某一個值,并行程式可能會更快地找到這個值(相對于使用的計算資源)。它隻是通過不同的路徑找到這個值而已。
當然,這不是通常情況,可以根據應用和具體輸入資料實作。考慮這麼一個例子:擷取密文的密鑰。在des加密标準中,使用[0, 256-1]間的某一個數字作為将一條消息(明文)轉換為晦澀難懂的密文的密鑰(key)。在對這個密文進行暴力破解時,需要嘗試所有可能的密鑰,直到将密文轉換為一個可讀的文本。假設每次嘗試解密這條消息在單個cpu上花費的時間為t,如果這個密鑰是數字255,那麼串行程式解決這個問題需要花費的時間tseq=(255+1)t。
現在,我們使用兩個cpu來解決這個問題。如果我們把包含256個密鑰的搜尋空間平均配置設定給兩個cpu。例如,第一個cpu搜尋[0, 255-1],第二個cpu搜尋[255, 256-1]。
那麼第二個cpu僅進行一次嘗試後,就會找到密鑰。那麼并行程式的加速比是:加速比
,效率是:效率
。期望使用更多的計算資源來解決某個問題是非常自然的。即,将計算資源增加到n,進而減少執行時間。這是個謬論!前面所述的簡單示例程式就可以證明這點:如果使用3個gpu來解決這個問題會發生什麼情況?第一個cpu的搜尋空間為:
,第二個cpu的搜尋空間為:
,第三個cpu的索引空間為。
是以,第二個cpu将會在嘗試了
次後找到正确密鑰。那麼,并行程式的加速比為加速比
,大大低于使用兩個cpu時的加速比。
用加速比來表征并行解決方案的有效性,這是有益的還是無益的呢?效率是計算資源使用率的測量方法,配置設定給程式的計算資源有多少是真正利用到的?效率低證明并行程式設計的比較糟糕,至少證明并行實作需要改進。
最後,我們需要知道當計算資源并且(或者)計算規模增加時并行算法的可擴充性如何。它擴充了嗎?
一般情況下,可擴充性表示一個系統有效處理不斷增長的工作負載的能力。在并行算法/平台的上下文中,可擴充性表示能夠解決更大問題規模或者能夠協調使用更多計算資源的能力。
有兩個量化可擴充性的名額:強可擴充性和弱可擴充性。
強可擴充性使用同式(1-2)相同的公式來定義:
(1-3)
這是一個關 于數量n的函數。其中,n表示解決同一個問題時,配置設定的處理器數目。
弱可擴充性同樣是關于n的函數,如下表示:
(1-4)
其中,tseq表示使用單個計算機解決問題的時間,t’par表示當問題規模增大n倍時的并行解決時間。
當使用gpu計算資源時,計算可擴充性會遇到很多問題:n的取值應該是多少?gpu一般會擁有成百甚至上千個計算核心。但是我們測試或者報告程式在一個gpu計算核心上的運作時間tseq是不科學的。如果我們這樣做,當計算可擴充性時,使用gpu全部的計算核心數目作為n是否合理?同時,gpu是一個托管裝置,它需要cpu來執行i/o操作,需要把cpu也計算在内嗎?
在這種情況下,可擴充性的計算可以有多種方式。為了避免争議,後面的章節在讨論異構計算平台時,隻使用加速比。