CPU 排程

負載平衡(load balancing)

想像超市的好幾條結帳通道:若一位收銀員前面排了大隊、另外兩位卻閒著,經理會揮手把顧客分流過去攤平人潮。多核心系統中的負載平衡就是那位經理——它設法讓就緒行程在核心間平均分散,使沒有一顆核心被淹沒、而其他核心無所事事,整體工作也更快完成。

它的運作方式(在逐核心執行佇列下):有兩種互補的機制。在推送遷移中,一個週期性的檢查會察看每顆核心的負載,發現不平衡時,主動把行程從過載的核心推到負載較輕的核心上。在拉取遷移中,一顆已清空自己佇列的閒置核心會伸手,從較忙核心的佇列拉一個等待中的行程過來。真實系統常兩者並用——拉取讓閒置核心不浪費週期、推送則修正較慢累積的不平衡。觸發通常是一個負載門檻,好讓系統不會為了微不足道的差異而把行程到處彈來彈去。

為什麼重要與它的成本:若沒有負載平衡,逐核心佇列可能嚴重失衡,使「擁有許多核心」這件事整個失去意義。但平衡並非免費,而誠實的張力就在這裡:每次遷移都違反處理器親和性,迫使一個行程在新核心的快取上「冷」啟動。所以激進的平衡可能因快取失誤而傷害效能,而怯懦的平衡又浪費閒置核心。好的排程器只在不平衡大到足以蓋過快取代價時才平衡——而在 NUMA 硬體上,它們還會盡量讓行程留在它的記憶體附近,而不只是留在工作附近。

核心 A 的執行佇列有八個就緒執行緒;核心 B 的是空的。拉取遷移:閒置的核心 B 從核心 A 的佇列抓一個執行緒過來執行。推送遷移:週期性的平衡器注意到 8 比 0 的差距,把三個執行緒從 A 移到 B,把負載攤平到大約 5 與 3。

推送與拉取遷移把工作分散到各核心;每次搬移都以親和性換取平衡。

負載平衡與處理器親和性是直接對手:每次再平衡的遷移都丟掉快取的暖度。恰當的平衡量是一個量測過的折衷,而非越多越好——過度平衡可能比輕微不平衡還慢。