在我的程式中,我有幾個執行緒隨進程一起啟動,並一直保留到程式結束。它們在應用程式的生命週期中會遇到不同的負載,有時它們都會以 100% 的速度運行。
預設情況下,Linux 執行緒調度程序將非常輕率地更改多核心系統上這些執行緒的親和力(IMO)。當我查看圖形進程監視器(gnome 中的監視器)中的彈跳圖時,我不禁認為這構成了某種開銷。
編輯:為了澄清,即使對於非常穩定的負載,線程也被調度在不同的核心上,即使它在圖像中不可見,但有時非常清楚的是,為每個線程選擇的核心經常「交換」。
這種親和力的不斷變化不會對性能產生不利影響嗎?
既然如此,為什麼要這樣實現呢?改變親和力有什麼好處?
我的猜測是:
- 磨損均衡-不要將所有工作放在一個核心上
- 無意 - 某些智慧演算法嘗試根據負載優化使用情況,但碰巧開銷不足以保證保持親和力而不是更改它。
答案1
如果您要在一個核心上運行所有線程,請購買更便宜的單核心硬體。
調度程序嘗試最大限度地利用所有核心。這意味著將線程分派到任何有空閒時間的核心。將執行緒從一個核心移動到另一個核心的成本很小,因此調度程序確實會盡力避免這種情況。但您通常不會太注意到這一點,因為不讓核心閒置的好處遠大於遷移執行緒的成本。如果執行緒使用的記憶體多於核心本機緩存,則尤其如此:如果執行緒使用的記憶體不在核心本機快取中,則將其遷移到另一個核心不會造成任何損失。
對工業級調度程序(例如 Linux 的調度程序)進行事後評估通常會使效能變得更差。
您顯示的圖表顯示各個核心上的負載未滿且略有變化,可能是因為您的系統作為一個整體受到當前正在執行的任務的 I/O 限制,而不是受到 CPU 功率的限制。它沒有以任何方式說明線程從一個核心移動到另一個核心的頻率。
答案2
這裡提供的快照也取決於核心的類型(版本)。版本 2.4 的舊核心親和力較差,導致執行緒的大量乒乓運動影響系統效能。從2.5開始的核心版本具有相對更好的親和力。
在基於多核心的系統上,親和力的設定可以避免在跨核心移動執行緒時發生快取失效,從而提高效能。
在基於 Linux 的多核心系統中,可以根據應用程式/需求的類型,使用進程的 sched_setaffinity/taskset 和執行緒的 pthread_setaffinity_np 來覆寫調度程式的親和行為(自然親和)。
內核鯊魚似乎提供了多核系統和親和力的更好的視覺表示。
另外,請注意頂部提供視覺支援來設定關聯性(以覆蓋調度程序)。