最近更新: 2011-03-15

某項多行程與多線程模式效能差異之評測分析

日前我做了一項大量資料計算效能評測工作。 評測內容是多行程(multi-processing)與多線程模式(multi-threading)的效能差異。

根據程式內部的資料計算方式內容,從理論與個人經驗,我直覺預期這項評測的多行程模式的效能會比較高。 有趣的是,公司同事(或者說多數資訊人員)則是習慣性地認為多線程模式的效能比較高。

回到正題。我的評測環境是在一臺 Intel Core Duo CPU (雙核心) 主機上進行,作業系統是 Ubuntu Linux, 評測程式碼是用 C 語言撰寫。

計算標的是十筆資料,全部載入記憶體(約200KB資料量),呼叫一萬次計算函式。 計算函式的內容在此不便透露,各位可以想像成資料壓縮與解縮。 計算過程中不做任何輸出工作,不在螢幕上顯示資訊,資料也不會寫入磁碟。

評測數據

單線模式

第一步,我先用傳統的單行程單線執行模式執行。其 CPU 使用量記錄圖如下:

單線執行模式 CPU 使用量記錄圖

各位可以看出,在此執行模式下,作業系統仍然會自行選擇比較有空的計算核心來運行。 故兩個計算核心會交錯被使用,但同時間僅使用一核心。 使用中的計算核心,其用量接近100%,完全滿載。

多線程模式

第二步,我再用眾人預期可以二倍速的多線程模式(multi-threading),以 pthread 配置兩個線程計算。 其 CPU 使用量記錄圖如下:

多線程執行模式CPU使用量

在多線程執行模式下,啟用兩個線程平行處理。 作業系統會將運算量平均分配在兩個計算核心之上。 但由於兩線程處於同一行程資源空間中,為協同資源同步,使CPU出現趨近連續的零碎閒置時間。 故兩核心的使用量呈現明顯起伏狀,未接近100%。

多行程模式

第三步,我用多行程模式(multi-processing),以 fork 配置兩個行程計算。 其 CPU 使用量記錄圖如下:

多行程執行模式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%

多工程式的執行效能往往出人意料,其結果不會是單一答案。 未經實際評測,不要太過肯定多線程模式就一定比較好。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/15356403.html

樂多舊回應
未留名 (#comment-21662627)
Wed, 16 Mar 2011 08:24:12 +0800
multithread 效能比較差,有沒有可能是因為 cache line false sharing 讓不同 thread 存取在同一個 cacheline 上的資料,造成效能下降?
未留名 (#comment-21668495)
Thu, 17 Mar 2011 12:07:42 +0800
的確非常令人意外
小弟對多工程式不熟
雖然有寫過一些些
但經驗不多
這篇文章讓我受益良多
謝謝
未留名 (#comment-21668811)
Thu, 17 Mar 2011 14:29:39 +0800
這跟不同重量的自由落體那一個速度較快,是一樣的道理,沒有經過實驗都很容易受到經驗的誤導啊
未留名 (#comment-21669177)
Thu, 17 Mar 2011 17:51:09 +0800
to Kevin:

計算函式使用第三方函數庫。沒有源碼,所以我也不能說到底是哪個環節的問題。
只知該函數庫並沒針對 multi-threading 的環境最佳化。
未留名 (#comment-21690989)
Thu, 31 Mar 2011 18:34:26 +0800
不知道版主有沒有興趣測一下
hyper threading 與 實體多核 之間的差異?
未留名 (#comment-21697873)
Wed, 06 Apr 2011 11:05:58 +0800
如果你說的 hyper threading 是指 Intel 推出的 CPU 架構。那麼這方面的差異,你可請教作業系統設計者。

我基本上只在作業系統抽象層看待這些事。不會關注到特定的硬體實際架構。
thomas.lee@octon.net(Thomas) (#comment-21738997)
Wed, 04 May 2011 11:39:59 +0800
請問當一台 Server 還有其他程式在 Running,
如果 CPU 負載一直被該程式吃滿維持 100% 是否會影響其他程式執行的效率....?

感謝...