Linux 核心101:NUMA下的競爭管理

liaochangjiang發表於2019-04-18

本文參考了以下這篇論文:

回顧一下上篇文章

上一篇文章 簡單地介紹了一下多 CPU 下的 NUMA 架構。NUMA 架構中將記憶體劃分為多個不同的區域,將CPU 和臨近的記憶體組成一個 node 節點,OS 排程的時候會優先使用臨近的記憶體,從而解決了之前 UMA 架構下 BUS 帶來的效能問題(因為多個 CPU 會對這一條匯流排產生競爭)。同時也講到了在MySQL在 NUMA 架構下遇到的 “swap insanity”問題,也就是當MySQL 佔用的記憶體超過 (100 / node 總數) % 時,由於『優先使用臨近記憶體』這個排程模式的存在,造成了記憶體分配不均,導致系統整體記憶體充足的情況下,依然出現大量『不正常』的的 swap 現象。如下圖所示:

Linux 核心101:NUMA下的競爭管理

本文內容概括

本文將從『資源競爭管理』的角度切入,將會看到UMA 時代的競爭管理演算法將不再適用於 NUMA,並給出具體的原因分析和解決方案。看完之後相信你一定會對 NUMA有更加深刻的理解,並對多CPU 時代的程式設計有個感性的認識。

UMA 競爭管理演算法對 NUMA 不適用

有共享資源的地方,就會有競爭。有競爭,就會有效能損失。

一直以來,多核系統的共享資源競爭都是一個大問題。核心之間互相競爭共享資源,比如 last-level cache(LLC)、系統請求佇列和記憶體管理器等。目前比較流行的解決方案叫做 contention-aware scheduler(競爭感知排程程式,下面簡稱為 CAS),也就是說它能夠區分在互相競爭共享資源的 threads,然後把他們分開到不同的 domain。有資料顯示,這種排程方法可以提高最壞情況下80%、平均10%的效能。

這種演算法在 UMA 中是有效的。但是需要考慮到的是, NUMA 相比 UMA 有一點很大的不同,那就是 UMA 只有一個 memory node,配備一個 memory controller;而 NUMA中 每個 node 裡面都有一個 memory node,各自配備了一個 memory controller,如下圖所示:16個核被分為了4個 node,每個 node 有一個獨立的 memory(當然每個核都可以訪問任意位置的記憶體)。

Linux 核心101:NUMA下的競爭管理

那麼這種排程方式到底起不起作用呢?如果只是簡單的想一下的話,也許會覺得為什麼不行呢?如果同一個 node 裡面的 threads 競爭特別激烈,那我就把其中一個移到另一個 node 上,雖然說這會帶來一定的延遲,但是競爭就解決了啊。

然後,事情沒那麼簡單,一切真理都來自於實踐,實踐發現,在 NUMA 上面實施這種排程演算法的時候,非但沒能很好地解決競爭,反而效能下降了30%。至於原因,下文將會給出。

為什麼不適用?

在 NUMA 架構下,CAS 會感知有哪些相互競爭的 threads,然後把其中一個移到不同的 domain 中。這會導致一種情況:thread的記憶體沒有分配在該thread 執行的那個 node 裡面,比如說上圖中,一個 thread 本來執行在 c1上,之後由於競爭被移到 c5上了,但是它的 memory 還在 M1。我們把這種由於移動 thread,導致 thread 和它的記憶體分家的行為稱作『NUMA-agnostic migrations』(agnostic 中文意思是不可知,自已意會一下~)。

NUMA-agnostic migrations導致了一些問題,比較明顯一點的是thread 獲取記憶體的延遲提高了,不過這還不是關鍵。更重要的是,NUMA-agnostic migrations無法緩解一些關鍵資源(memory controller)的競爭問題,甚至還引起對更多資源(interconnect connection)的競爭。

下面這張圖很重要,請仔細看:

Linux 核心101:NUMA下的競爭管理

解釋一下:T 和 C 分別表示兩個程式(thread)

  • 圖0:兩個程式相安無事,沒有競爭關係。
  • 圖1:CT 的記憶體在一個 node,對 memory controller(MC) 產生了競爭關係。(應該還有訪問延遲,圖中可能忘記標註了)
  • 圖2: 兩個程式都需要試用進行CPU 之間的快速通道,產生了interconnect connection(IC)競爭。同時還有訪問遠端 memory 帶來的訪問延遲(RL)。
  • 圖3:memory controller (MC)競爭,加上遠端訪問延時(RL)。
  • 圖4:TC 位於一個 CPU 裡面,對 last-level cache(CA) 產生競爭關係。
  • 圖5:CA + RL
  • 圖6:CA + MC
  • 圖7:最壞的情況,CA + MC + IC + MC

實驗發現,圖3的效能下降了110%。原因在於 threads 還是在相互競爭 memory controller。NUMA-agnostic migrations在遷移 thread 的時候,很有可能最後會導致這種情況出現。

假如現在有兩個threads,A 和 B,A 執行在圖一中的 c1上,B 執行在 c2上,他們之間存在競爭關係(競爭last-level cache)。現在有一個 contention-aware 排程器檢測到了 A 和 B 的競爭關係,於是把 B 移動到 c5上去了,現在A 和 B 不再競爭 last-level cache 了。事實上在 UMA 系統中這的確是起作用了(雖然對於 memory controller 的競爭還是存在的)。

但是對於 NUMA,A 和 B 的 memory 還在一個地方,對於 最關鍵資源memory controller 的競爭沒有得到解決。而且還引來了兩個問題,這兩個問題會嚴重影響 B 的效能。

  1. interconnect connection。(這點影響會很嚴重)
  2. remote access。

總結一下

NUMA-agnostic migrations無法提高 甚至還會降低NUMA競爭管理的效能,按照對效能的影響程度排序有:

  1. 沒能夠解決對 memory controller 的競爭關係(memory 還在原來那個地方)。
  2. 引起了額外的 interconnect connection。
  3. 引起了額外的 remote access。

原論文中還提到了作者自己研究出的一種解決方案,有興趣的同學可以去啃一下原文。

相信你看完了,應該對 NUAM 架構有了一個比較感性的認識了吧。覺得寫的不錯(看在gakki 的情面上)不點個贊鼓勵一下?

Linux 核心101:NUMA下的競爭管理

Linux 核心101:NUMA下的競爭管理

廣告時間,歡迎大家關注我的微信公眾號。同時本文同步於 github: github.com/liaochangji…

Linux 核心101:NUMA下的競爭管理

相關文章