記憶體瘋狂換頁!CPU怒批作業系統

記憶體訪問瓶頸

我是CPU一號車間的阿Q,前一陣子我們廠里發生了一件大喜事,老闆拉到了一筆投資,準備擴大生產規模。

不過老闆挺摳門的,拉到了投資也不給我們漲點工資,就知道讓我們拚命幹活,壓榨我們的勞動力。

老闆說了,投資的錢要用來添置設備,招聘新員工,咱們原來就有八個車間了,這一下直接double,變成了十六個!我們的工資要是也能double就好了···

現在我們變成了一個16核的CPU啦!

原以為我們生產效率也能double,沒想到卻遇到了新的問題。

我們CPU裡面各個車間訪問記憶體都要通過記憶體控制器和匯流排系統,有時候碰到幾個車間都要訪問記憶體,就得要競爭。

以前我們八個車間的時候競爭情況還不是很激烈,大家互相謙讓一下也就罷了。現在變成了十六個車間都要過獨木橋,這競爭一下就激烈了,尤其是我們這幫老員工基本不會讓著新來的,為了此事經常發生不愉快。

記憶體訪問出現了瓶頸,這性能自然是折損嚴重。

NUMA架構

老闆把這一切都看在眼裡,私下裡找了我、二號車間的虎子還有匯流排主任開了個小會。

「你們幾個都是廠里的核心員工,對廠里目前的問題你們怎麼看?」,老闆問我們幾個。

我和虎子互相瞅了瞅,都沒說話。

這時匯流排主任開口了:「老闆,現在的問題是訪問記憶體的路只有一條,大家都要來擠,難免會發生摩擦,影響工作性能。要想從根本解決問題,最好再建一條路」

「再建一條路,什麼意思?」

「我建議把新擴建的那8個車間獨立出去,建一個分廠。然後再把記憶體分一下,讓兩個廠各管理一部分。一來可以減少新老員工之間的矛盾,二來可以減少大家訪問記憶體擁擠造成的資源浪費。再說了,萬一以後繼續擴大規模還可以繼續用這個辦法」,匯流排主任繼續說到。

領導正低頭思索,我倒是想到了一個問題:「主任,要是我們一號核執行的執行緒要訪問的記憶體頁面不在我們廠管理的記憶體上,在他們分廠怎麼辦呢?」

「嗯,這樣的話,兩個廠之間需要通訊,如果訪問的記憶體不在自己管轄的範圍,就要互相幫忙傳遞一下」

老闆拍了下桌子:「好主意!就這麼辦!」

第二天,老闆召集16個車間的代表,匯流排主任,還有作業系統那邊負責記憶體管理的負責人小李,一起開了一個大會,會上正式通過了新的技術方案。

還給這項技術取了一個名字:NUMA(Non Uniform Memory Access),非一致性記憶體訪問。

現有的16個車間拆分成兩個CPU工廠,叫做兩個NUMA節點(Node),每個節點直接連接一部分記憶體,兩個節點之間有專門的的inter-connect通道。各節點直接訪問自己管理的記憶體叫Local Access,通過inter-connect通道訪問其他分廠管理的記憶體叫做Remote Access。很顯然,前者的訪問速度要比後者快得多,所以這也是這項技術名字的由來:非一致性記憶體訪問。

新的組織架構調整過後,廠里的工作效率提升不少,矛盾摩擦也少了很多,又可以愉快的幹活了。

作業系統支援

我們的組織架構調整了,作業系統那邊可忙壞了。為了支援我們新的架構,作業系統不得不配合著做一些調整。

首先是快取的問題,作業系統的進程&執行緒調度管理部門需要注意盡量不要跨NUMA節點進行調度執行緒,不能讓一個執行緒一會兒在隔壁分廠運行,一會兒又在我們廠運行,這樣建立的快取就失效了。

還有就是記憶體親和性的問題了,為了能得到更快的記憶體訪問速度,作業系統的記憶體管理部門制定了一個記憶體分配策略,執行緒在哪個NUMA節點內執行,那就把記憶體分配到那個節點直接連接的記憶體中,避免跨節點的記憶體訪問。

還別說,作業系統這麼一優化調整,工作效率真是提升了不少呢。

然而好景不長,就因為這個調整,新的問題又雙叒叕出現了~~~

MySQL的問題

最近一段時間,發生了一件怪事,不知道怎麼回事,我們分廠管轄的記憶體很快耗光了,但隔壁分廠管理的記憶體還有很多空間。

作業系統不去分配那邊的記憶體頁面,卻讓我們一個勁的把記憶體頁面swap到硬碟上去,騰挪空間。我們花了大量時間在這上邊,搞得我們業績下滑,還比不上隔壁分廠那幫新人。

終於有一天,忍不了了,我夥同廠里幾個老傢伙,把作業系統記憶體管理部門的小李又叫來了。

「你們怎麼回事,就不能分配隔壁二號節點分廠管轄的記憶體嗎,明明還有那麼多空間,卻讓我們忙個不停」,我有點生氣。

小李滿臉無辜的說到:「不瞞你們各位,前幾天有人來我們Linux帝國開設了一家新公司,叫MySQL,這傢伙是個吃記憶體大戶啊,一上來就要吃掉幾十G,你們廠管轄的記憶體大半都被它給吃掉了」

虎子問到:「這跟我們有什麼關係,你別推卸責任啊」

「上次我來開會,你們不是搞了個什麼NUMA架構嗎,訪問本地連接的記憶體要比訪問遠程記憶體快一些嘛,所以我們制定了記憶體親和性策略嘛,執行緒在哪個NUMA節點執行,就把記憶體分配到哪個節點直接連接的記憶體,想著這樣能提升性能嘛」,小李繼續委屈的說到。

「那也不能死腦筋啊,訪問遠程記憶體雖然比不上訪問本地記憶體快,那也比一個勁的把頁面從記憶體和硬碟上換來換去的強啊,你真是好心辦壞事!」

被我們這樣一說,小李也意識到了這樣做的問題,「我回去回饋一下大家的意見,調整一下我們的策略」

過了幾天,作業系統那邊上了新的記憶體分配策略,將記憶體均勻的分配到各個NUMA節點,我們再也不用坑次坑次的把數據從記憶體和硬碟之間搬來搬去了。

NUMA雖好,可要是用得不好,只會徒增煩惱啊~

彩蛋

Linux帝國最近又來了一家公司,發布了一項工程招標。

「聽說了嗎,我們廠居然沒中標」

「怎麼可能,除了我們還有誰干這活」

「聽說是一家叫GPU的工廠」

預知後事如何,請關注後續精彩······

往期TOP5文章

CPU明明8個核,網卡為啥拚命折騰一號核?

因為一個跨域請求,我差點丟了飯碗

完了!CPU一味求快出事兒了!

哈希表哪家強?幾大程式語言吵起來了!

一個HTTP數據包的奇幻之旅