本博客已經(jīng)遷移至:本文將分析是否Huge Page在任何條件下(特別是NUMA架構(gòu)下)都能帶來(lái)性能提升。
http://cenalulu.github.io/
為了更好的體驗(yàn),請(qǐng)通過(guò)此鏈接閱讀:http://cenalulu.github.io/linux/huge-page-on-numa/
文章歡迎轉(zhuǎn)載,但轉(zhuǎn)載時(shí)請(qǐng)保留本段文字,并置于文章的頂部作者:盧鈞軼(cenalulu)本文原文地址:http://cenalulu.github.io/linux/huge-page-on-numa/
在閱讀本文之前,需要讀者至少了解以下基礎(chǔ)知識(shí)
Chip Multi PRocessing aware Linux Kernel Scheduler
論文在正式開(kāi)始本文分析前,我們先大概介紹下Huge Page的歷史背景和使用場(chǎng)景。
為什么需要Huge Page了解CPU Cache大致架構(gòu)的話,一定聽(tīng)過(guò)TLB Cache。Linux
系統(tǒng)中,對(duì)程序可見(jiàn)的,可使用的內(nèi)存地址是Virtual Address
。每個(gè)程序的內(nèi)存地址都是從0開(kāi)始的。而實(shí)際的數(shù)據(jù)訪問(wèn)是要通過(guò)Physical Address
進(jìn)行的。因此,每次內(nèi)存操作,CPU都需要從page table
中把Virtual Address
翻譯成對(duì)應(yīng)的Physical Address
,那么對(duì)于大量?jī)?nèi)存密集型程序來(lái)說(shuō)page table
的查找就會(huì)成為程序的瓶頸。所以現(xiàn)代CPU中就出現(xiàn)了TLB(Translation Lookaside Buffer) Cache用于緩存少量熱點(diǎn)內(nèi)存地址的mapping關(guān)系。然而由于制造成本和工藝的限制,響應(yīng)時(shí)間需要控制在CPU Cycle級(jí)別的Cache容量只能存儲(chǔ)幾十個(gè)對(duì)象。那么TLB Cache在應(yīng)對(duì)大量熱點(diǎn)數(shù)據(jù)Virual Address
轉(zhuǎn)換的時(shí)候就顯得捉襟見(jiàn)肘了。我們來(lái)算下按照標(biāo)準(zhǔn)的Linux頁(yè)大小(page size) 4K,一個(gè)能緩存64元素的TLB Cache只能涵蓋4K*64 = 256K
的熱點(diǎn)數(shù)據(jù)的內(nèi)存地址,顯然離理想非常遙遠(yuǎn)的。于是Huge Page就產(chǎn)生了。Tips: 這里不要把Virutal Address
和Windows上的虛擬內(nèi)存搞混了。后者是為了應(yīng)對(duì)物理內(nèi)存不足,而將內(nèi)容從內(nèi)存換出到其他設(shè)備的技術(shù)(類似于Linux的SWAP機(jī)制)。
什么是Huge Page既然改變不了TLB Cache的容量,那么只能從系統(tǒng)層面增加一個(gè)TLB Cache entry所能對(duì)應(yīng)的物理內(nèi)存大小,從而增加TLB Cache所能涵蓋的熱點(diǎn)內(nèi)存數(shù)據(jù)量。假設(shè)我們把Linux Page Size
增加到16M
,那么同樣一個(gè)容納64個(gè)元素的TLB Cache就能顧及64*16M = 1G
的內(nèi)存熱點(diǎn)數(shù)據(jù),這樣的大小相較上文的256K
就顯得非常適合實(shí)際應(yīng)用了。像這種將Page Size
加大的技術(shù)就是Huge Page
。
了解了Huge Page的由來(lái)和原理后,我們不難總結(jié)出能從Huge Page受益的程序必然是那些熱點(diǎn)數(shù)據(jù)分散且至少超過(guò)64個(gè)4K Page Size的程序。此外,如果程序的主要運(yùn)行時(shí)間并不是消耗在TLB Cache Miss后的Page Table Lookup上,那么TLB再怎么大,Page Size再怎么增加都是徒勞。在LWN的一篇入門介紹中就提到了這個(gè)原理,并且給出了比較詳細(xì)的估算方法。簡(jiǎn)單的說(shuō)就是:先通過(guò)oprofile
抓取到TLB Miss
導(dǎo)致的運(yùn)行時(shí)間占程序總運(yùn)行時(shí)間的多少,來(lái)計(jì)算出Huge Page所能帶來(lái)的預(yù)期性能提升。簡(jiǎn)單的說(shuō),我們的程序如果熱點(diǎn)數(shù)據(jù)只有256K,并且集中在連續(xù)的內(nèi)存page上,那么一個(gè)64個(gè)entry的TLB Cache就足以應(yīng)付了。說(shuō)道這里,大家可能有個(gè)疑問(wèn)了:既然我們比較難預(yù)測(cè)自己的程序訪問(wèn)邏輯是否能從開(kāi)啟Huge Page中受益。反正Huge Page看上去只改了一個(gè)Page Size,不會(huì)有什么性能損失。那么我們就索性對(duì)所有程序都是用Huge Page好啦。其實(shí)這樣的想法是完全錯(cuò)誤的!也正是本文想要介紹的一個(gè)主要內(nèi)容,在目前常見(jiàn)的NUMA體系下Huge Page也并非萬(wàn)能鑰匙,使用不當(dāng)甚至?xí)沟贸绦蚧蛘邤?shù)據(jù)庫(kù)性能下降10%。下面我們重點(diǎn)分析。
Large Pages May Be Harmful on NUMA Systems一文的作者曾今做過(guò)一個(gè)實(shí)驗(yàn),測(cè)試Huge Page在NUMA環(huán)境的各種不同應(yīng)用場(chǎng)景下帶來(lái)的性能差異。從下圖可以看到Huge Page對(duì)于相當(dāng)一部分的應(yīng)用場(chǎng)景并不能很好的提升性能,甚至?xí)?lái)高達(dá)10%的性能損耗。
性能下降的原因主要有以下兩點(diǎn)
CPU對(duì)同一個(gè)Page搶占增多對(duì)于寫操作密集型的應(yīng)用,Huge Page會(huì)大大增加Cache寫沖突的發(fā)生概率。由于CPU獨(dú)立Cache部分的寫一致性用的是MESI協(xié)議
,寫沖突就意味:
類比到數(shù)據(jù)庫(kù)就相當(dāng)于,原來(lái)一把用來(lái)保護(hù)10行數(shù)據(jù)的鎖,現(xiàn)在用來(lái)鎖1000行數(shù)據(jù)了。必然這把鎖在線程之間的爭(zhēng)搶概率要大大增加。
連續(xù)數(shù)據(jù)需要跨CPU讀取(False Sharing)從下圖我們可以看到,原本在4K小頁(yè)上可以連續(xù)分配,并因?yàn)檩^高命中率而在同一個(gè)CPU上實(shí)現(xiàn)locality的數(shù)據(jù)。到了Huge Page的情況下,就有一部分?jǐn)?shù)據(jù)為了填充統(tǒng)一程序中上次內(nèi)存分配留下的空間,而被迫分布在了兩個(gè)頁(yè)上。而在所在Huge Page中占比較小的那部分?jǐn)?shù)據(jù),由于在計(jì)算CPU親和力的時(shí)候權(quán)重小,自然就被附著到了其他CPU上。那么就會(huì)造成:本該以熱點(diǎn)形式存在于CPU2 L1或者L2 Cache上的數(shù)據(jù),不得不通過(guò)CPU inter-connect去remote CPU獲取數(shù)據(jù)。假設(shè)我們連續(xù)申明兩個(gè)數(shù)組,Array A
和Array B
大小都是1536K。內(nèi)存分配時(shí)由于第一個(gè)Page的2M沒(méi)有用滿,因此Array B
就被拆成了兩份,分割在了兩個(gè)Page里。而由于內(nèi)存的親和配置,一個(gè)分配在Zone 0,而另一個(gè)在Zone 1。那么當(dāng)某個(gè)線程需要訪問(wèn)Array B時(shí)就不得不通過(guò)代價(jià)較大的Inter-Connect去獲取另外一部分?jǐn)?shù)據(jù)。
delays re-sulting from traversing a greater physical distance to reach a remote node, are not the most important source of performance overhead. On the other hand, congestion on interconnect links and in memory controllers, which results from high volume of data flowing across the system, can dramatically hurt performance.
對(duì)策理想Under interleaving, the memory latency re- duces by a factor of 2.48 for Streamcluster and 1.39 for PCA. This effect is entirely responsible for performance improvement under the better policy. The question is, what is responsible for memory latency improvements? It turns out that interleaving dramatically reduces memory controller and interconnect congestion by allevi- ating the load imbalance and mitigating traffic hotspots.
我們先談?wù)劺硐肭闆r。上文提到的論文其實(shí)他的主要目的就是討論一種適用于NUMA架構(gòu)的Huge Page自動(dòng)內(nèi)存管理策略。這個(gè)管理策略簡(jiǎn)單的說(shuō)是基于Carrefour
的一種對(duì)Huge Page優(yōu)化的變種。(注:不熟悉什么是Carrefour
的讀者可以參看博客之前的科普介紹或者閱讀原文)下面是一些相關(guān)技術(shù)手段的簡(jiǎn)要概括:
False Sharing
,監(jiān)控造成大量Cache Miss的Page,并進(jìn)行拆分重組。將同一CPU親和的數(shù)據(jù)放在同一個(gè)Page中談完了理想,我們看看現(xiàn)實(shí)。現(xiàn)實(shí)往往是殘酷的,由于沒(méi)有硬件級(jí)別的PMU(Performance Monitor Unit)支持,獲取精準(zhǔn)的Page訪問(wèn)和Cache Miss信息性能代價(jià)非常大。所以上面的理想僅僅停留在實(shí)驗(yàn)和論文階段。那么在理想實(shí)現(xiàn)之前,我們現(xiàn)在該怎么辦呢?答案只有一個(gè)就是測(cè)試
實(shí)際測(cè)試實(shí)際測(cè)試的結(jié)果最具有說(shuō)服力。所謂實(shí)際測(cè)試就是把優(yōu)化對(duì)象給予真實(shí)環(huán)境的壓力模擬。通過(guò)對(duì)比開(kāi)啟和關(guān)閉Huge Page時(shí)的性能差別來(lái)驗(yàn)證Huge Page是否會(huì)帶來(lái)性能提升。當(dāng)然大多數(shù)應(yīng)用程序,要想模擬真實(shí)環(huán)境下的運(yùn)行情況是非常困難的。那么我們就可以用下面這種理論測(cè)試
理論測(cè)試理論測(cè)試可以通過(guò)profile預(yù)估出Huge Page能夠帶來(lái)的潛在提升。具體原理就是計(jì)算當(dāng)前應(yīng)用程序運(yùn)行時(shí)TLB Miss導(dǎo)致的Page Walk成本占程序總執(zhí)行時(shí)間的占比。當(dāng)然這種測(cè)試方式?jīng)]有把上文提到的那兩種性能損失考慮進(jìn)去,所以只能用于計(jì)算Huge Page所能帶來(lái)的潛在性能提升的上限。如果計(jì)算出來(lái)這個(gè)值非常低,那么可以認(rèn)為使用Huge Page則會(huì)帶來(lái)額外的性能損失。具體方法見(jiàn)LWN上介紹的方法具體的計(jì)算公式如下圖:
如果沒(méi)有hardware的PMU支持的話,計(jì)算需要用到oprofile
和calibrator
。
并不是所有的優(yōu)化方案都是0性能損失的。充分的測(cè)試和對(duì)于優(yōu)化原理的理解是一個(gè)成功優(yōu)化的前提條件。
Reference新聞熱點(diǎn)
疑難解答
圖片精選