某項多行程與多線程模式效能差異之評測分析
日前我做了一項大量資料計算效能評測工作。 評測內容是多行程(multi-processing)與多線程模式(multi-threading)的效能差異。
根據程式內部的資料計算方式內容,從理論與個人經驗,我直覺預期這項評測的多行程模式的效能會比較高。 有趣的是,公司同事(或者說多數資訊人員)則是習慣性地認為多線程模式的效能比較高。
回到正題。我的評測環境是在一臺 Intel Core Duo CPU (雙核心) 主機上進行,作業系統是 Ubuntu Linux, 評測程式碼是用 C 語言撰寫。
計算標的是十筆資料,全部載入記憶體(約200KB資料量),呼叫一萬次計算函式。 計算函式的內容在此不便透露,各位可以想像成資料壓縮與解縮。 計算過程中不做任何輸出工作,不在螢幕上顯示資訊,資料也不會寫入磁碟。
評測數據
單線模式
第一步,我先用傳統的單行程單線執行模式執行。其 CPU 使用量記錄圖如下:
各位可以看出,在此執行模式下,作業系統仍然會自行選擇比較有空的計算核心來運行。 故兩個計算核心會交錯被使用,但同時間僅使用一核心。 使用中的計算核心,其用量接近100%,完全滿載。
多線程模式
第二步,我再用眾人預期可以二倍速的多線程模式(multi-threading),以 pthread 配置兩個線程計算。 其 CPU 使用量記錄圖如下:
在多線程執行模式下,啟用兩個線程平行處理。 作業系統會將運算量平均分配在兩個計算核心之上。 但由於兩線程處於同一行程資源空間中,為協同資源同步,使CPU出現趨近連續的零碎閒置時間。 故兩核心的使用量呈現明顯起伏狀,未接近100%。
多行程模式
第三步,我用多行程模式(multi-processing),以 fork 配置兩個行程計算。 其 CPU 使用量記錄圖如下:
啟用兩個行程平行處理。作業系統將運算量平均分配在兩個計算核心之上。 由於兩行程各擁獨立的行程資源空間,不需另耗資源協調同步工作,故兩核心可不閒置地連續運算,其負載皆處於100%。 運算時間僅為單線執行模式的一半
使用時間
將相同的十筆資料進行一萬次計算,在不同執行模式下所耗時間如下表:
- 單行程單線執行: 77秒
- 雙線程執行: 83秒
- 雙行程執行: 36秒
雙線程模式不僅沒有二倍速,反而還比單行程單線慢。 倒是雙行程模式充分利用了雙計算核心的威力,執行時間砍了一半。
分析
當計算標的資料已經被載入記憶體時,計算動作只牽涉到CPU與記憶體間的資料交換動作。 由於兩者間的 I/O 速度差異不大,CPU不會使用很多時間等待記憶體的資料複製工作,故CPU處於低閒置狀態。
當CPU處於低閒置狀態的情況下,使用多線程模式反而額外增添資源同步的協調動作,導致效能降低。 反觀多行程模式下,由於不需額外的資源同步協調動作,故CPU反而能全速運轉,使其效能隨計算核心數量線性提高。
一般論多線程模式之效能較高的說法,其前導條件是 CPU 在計算過程中經常處於閒置狀態。 而多線程能夠利用這些閒置時間,降低 CPU 閒置的機會,故能提高計算效能。
例如在計算過程中,資料的讀寫動作牽涉兩方設備,若讀、寫雙方的 I/O 效能差異很大, 那麼在資料於設備間搬移時,CPU 就會處於等待閒置的狀態。 此時若有另一個線程可以利用這段 CPU 閒置時間進行運算,那麼就能提昇程式的整體計算效能。
但在本文的評測對象中,其資料都是在記憶體間搬移, I/O 效能差異極小。理論上可推估 CPU 的閒置時間不會太多。 再者,我從它的單線執行模式中,就已經觀察到 CPU 使用量在計算過程中總是頂在100%處,幾乎沒有閒置。 在這種滿載狀態下,進行多線程運算往往只會加重額外的同步工作負擔。 結合兩點,故我才會預期多行程模式的效能比較高。
儘管如此,實際評測結果還是出我意料。
我原本預期的執行時間比是 100% : 95% : 67%
,但實際評測結果則是 100% : 107% : 47%
。
多工程式的執行效能往往出人意料,其結果不會是單一答案。 未經實際評測,不要太過肯定多線程模式就一定比較好。
樂多舊回應