透明大页相关内核参数_透明大内存页Hugepage支持
==目標(biāo)==
在linux2.6.38之前,處理大容量內(nèi)存工作集的高性能關(guān)鍵計(jì)算應(yīng)用是運(yùn)行在libhugetlbfs之上,必須依賴于
hugetlbfs,。透明Hugepage支持是一種替代手段,它使用大內(nèi)存頁,并且虛擬內(nèi)存頁的大小可以動(dòng)態(tài)變化,沒有hugetlbfs的缺點(diǎn)。
目前只適用于匿名內(nèi)存映射,但未來可以擴(kuò)展到tmpfs的papecache層。
大內(nèi)存頁的優(yōu)點(diǎn):
巨大的頁面可以通過減少缺頁提升性能(一次缺頁分配大塊的內(nèi)存),還可以通過減少虛擬地址到物理地址的轉(zhuǎn)換成本(減少轉(zhuǎn)化次數(shù)),甚至可以避免地址轉(zhuǎn)換。如果處理器必須轉(zhuǎn)換一個(gè)虛擬地址,它必須通過多達(dá)四層頁表。處理器保持一個(gè)“翻譯后備緩沖器(TLB)的緩存的轉(zhuǎn)換結(jié)果。TLB的容量很小,一般是128條指令轉(zhuǎn)換、32條數(shù)據(jù)轉(zhuǎn)換。非常容易被填滿,從而必須進(jìn)行大量的地址轉(zhuǎn)換。例如:2m的頁大小只需要一個(gè)tlb項(xiàng),而4k的頁大小就需要512個(gè)tlb項(xiàng)。通過內(nèi)核地址使用大內(nèi)存頁,可以減少tlb的壓力。
基于以上原因,使用大內(nèi)存頁的程序會(huì)運(yùn)行的很快。
hugetlbfs 缺點(diǎn):
(1)巨頁必須在內(nèi)核啟動(dòng)時(shí)刻進(jìn)行設(shè)置,并且需要應(yīng)用程序顯示映射。
(2)更傾向于大的專有數(shù)據(jù)庫管理系統(tǒng)
==設(shè)計(jì)==
- “優(yōu)雅的回退”:不具有透明hugepage的內(nèi)存管理系統(tǒng)可以會(huì)退到不使用透明hugepage,而使用常規(guī)頁面和各自的規(guī)則pmd/pte映射
- ,如果因?yàn)閮?nèi)存碎片導(dǎo)致大內(nèi)存頁分配失敗,這時(shí)系統(tǒng)應(yīng)該優(yōu)雅的使用常規(guī)頁代替,并將其寫入到相同的vma中,并且沒有任何故障、重大延遲或用戶態(tài)通知。
- 如果有些任務(wù)結(jié)束,越來越多的大頁面變成可用(無論是立即在伙伴系統(tǒng)或通過虛擬內(nèi)存),常規(guī)頁分配的物理內(nèi)存應(yīng)該通過khugepaged自動(dòng)遷往大內(nèi)存頁.
- 它并不需要保留內(nèi)存,只要有可能就會(huì)使用大頁面。
(唯一可能保留的kernelcore = ?避免不可移動(dòng)的頁面片段去分裂所有內(nèi)存,但這樣一個(gè)調(diào)整不特定于透明hugepage支持,它是一個(gè)通用的適用于所有的動(dòng)態(tài)內(nèi)存高階分配)
- 這個(gè)最初只支持提供匿名內(nèi)存區(qū),但將來會(huì)擴(kuò)展到tmpfs和pagecache
與hugetlbfs通過將不可用內(nèi)存用來作為cache或者可移動(dòng)的(或者甚至無法移動(dòng)實(shí)體)的保留內(nèi)存方式相比,透明Hugepage可以使空閑內(nèi)存利最大化。它不需要保留內(nèi)存,以防止大內(nèi)存頁分配。這對(duì)用戶態(tài)是透明的。大內(nèi)存頁允許分頁和所有其他的先進(jìn)的虛擬技術(shù),并且對(duì)用戶是透明的,不需要修改應(yīng)用程序來使用這些技術(shù)。
應(yīng)用可以更好的使用這些功能。例如可以避免有優(yōu)化之前的malloc(4k)的mmap系統(tǒng)洪水。這種優(yōu)化不是強(qiáng)制的,khugepaged會(huì)處理理那些不使用大內(nèi)存的來處理大量內(nèi)存的應(yīng)用程序。
在某些情況下,系統(tǒng)范圍使用大頁面,會(huì)導(dǎo)致應(yīng)用分配更多的內(nèi)存資源。例如應(yīng)用程序MMAP了一大塊內(nèi)存,但是只涉及1個(gè)字節(jié),在這種情況下,2M頁面代替4K頁的分配沒有任何好處,這就是為什么禁用全系統(tǒng)大頁面,而只針對(duì)MADV_HUGEPAGE區(qū)使用的原因。
嵌入式系統(tǒng)僅僅在madvise區(qū)域使能大頁面分配可以消除浪費(fèi)內(nèi)存的任何風(fēng)險(xiǎn),并且程序運(yùn)行的更快。
== sysfs==
透明Hugepage支持可以被完全禁用(多為調(diào)試目的)或只啟用MADV_HUGEPAGE(以避免消耗更多的內(nèi)存資源的風(fēng)險(xiǎn))或啟用系統(tǒng)
范圍。
echo always >/sys/kernel/mm/transparent_hugepage/enabled
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
echo never >/sys/kernel/mm/transparent_hugepage/enabled
它也可以限制在創(chuàng)造大頁面的內(nèi)存碎片整理的影響,他們不是立即對(duì)madvise區(qū)空閑或從未嘗試碎片整理內(nèi)存而使用規(guī)則頁面,除非是立即可用。顯然,我們使用CPU來碎片整理內(nèi)存,希望獲得的更多的大內(nèi)存頁,而不是普通頁面。這并不是保證,但它更可能的情況下分配為MADV_HUGEPAGE區(qū)。
echo always >/sys/kernel/mm/transparent_hugepage/defrag
echo madvise >/sys/kernel/mm/transparent_hugepage/defrag
echo never >/sys/kernel/mm/transparent_hugepage/defrag
khugepaged會(huì)自動(dòng)啟動(dòng)時(shí)當(dāng)transparent_hugepage/enabled設(shè)置為“always”或“madvise",它會(huì)自動(dòng)關(guān)機(jī),如果它被設(shè)置為“never”。
khugepaged通常在低頻運(yùn)行。
echo 0 >/sys/kernel/mm/transparent_hugepage/khugepaged/defrag
echo 1 >/sys/kernel/mm/transparent_hugepage/khugepaged/defrag
你還可以控制khugepaged每次掃描多少頁。
/sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan
掃描間隔(毫秒)
/sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs
當(dāng)分配大內(nèi)存失敗等待多少毫秒來壓制下一個(gè)大內(nèi)存頁的分配嘗試。
/sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs
可以看出,倒塌的內(nèi)存頁數(shù)量
/sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed
每次掃描:
/sys/kernel/mm/transparent_hugepage/khugepaged/full_scans
==引導(dǎo)參數(shù)==
你可以改變透明Hugepage的默認(rèn)支持。
通過內(nèi)核命令行參數(shù)"transparent_hugepage=always" or
"transparent_hugepage=madvise" or "transparent_hugepage=never"。
==需要重新啟動(dòng)應(yīng)用程序==
transparent_hugepage/enabled 只影響未來行為。因此,使它們有效,你需要重新啟動(dòng)任何
應(yīng)用程序可以一直使用大頁面。這也適用于注冊khugepaged的內(nèi)存區(qū)。
== get_user_pages和follow_page ==
get_user_pages和follow_page在hugepage上運(yùn)行,將返回
像往常一樣的頭或尾頁(正如hugetlbfs所做的)。
多數(shù)GUP用戶只關(guān)心實(shí)際的物理頁面地址和其I/O完成后的釋放,所以他們將不會(huì)注意到的頁面其實(shí)是巨頁的。但如果驅(qū)動(dòng)程序操作頁面結(jié)構(gòu)(如檢查起始頁、末尾頁的page->mapping或相關(guān)的其他位),它應(yīng)去檢查頭頁。
注意:對(duì)GUP API沒有新的約束,跟hugetlbfs具有相同的約束。所以任何在hugetlbfs中操作GUP的驅(qū)動(dòng)可以在
透明hugepage支持映射中運(yùn)行的很多。
如果你不能處理通過follow_page返回的混合頁,FOLL_SPLIT位可以被指定為follow_page參數(shù),這樣它將會(huì)返回之前分離巨頁。
==優(yōu)化應(yīng)用程序==
要保證內(nèi)核立即映射到一個(gè)2M的頁面在任何內(nèi)存區(qū)域中,在mmap區(qū)域必須是hugepage對(duì)齊。 posix_memalign()可以提供這種保證。
== Hugetlbfs ==
您可以使用在配置透明巨頁功能的內(nèi)核中使用hugetlbfs。除了沒有整體內(nèi)存碎片外,其他沒有區(qū)別。所有屬于hugetlbfs的通用功能都保存并且不受影響。 libhugetlbfs也將像以前一樣正常工作。
==優(yōu)雅的回退==
查詢pagetables的時(shí)候可以使用split_huge_page_pmd 檢查pmd_offset返回的pmd。
如果沒有查詢pagetables并且碰上一個(gè)物理hugepage但你不能在你的代碼處理它本身,可以使用split_huge_page分離它。
==了解hugepage代碼的鎖定==
我們要盡可能知道hugepage代碼,使用split_huge_page()或split_huge_page_pmd()有代價(jià)的。
為了使查詢頁表時(shí)意識(shí)到 huge pmd,你需要做的是調(diào)用pmd_trans_huge 在pmd_offset返回后。您必須持有mmap_sem(讀或?qū)?,確保huge pmd不能被khugepaged創(chuàng)建(khugepaged collapse_huge_page在獲取mmap_sem和anon_vma lock在寫模式下執(zhí)行)。
如果pmd_trans_huge返回false,就走舊代碼路徑。相反,如果pmd_trans_huge返回true,你必須要獲取 page_table_lock和重新執(zhí)行pmd_trans_huge。page_table_lock將防止將huge pmd轉(zhuǎn)換成常規(guī)pmd(split_huge_page可以并行執(zhí)行檢查頁表)。如果第二次pmd_trans_huge返回flase,你應(yīng)該丟棄page_table_lock和執(zhí)行以前的代碼路徑。否則你應(yīng)該執(zhí)行pmd_trans_splitting。pmd_trans_splitting返回true,這意味著split_huge_page已經(jīng)在分裂頁面中。因此,如果pmd_trans_splitting返回true,丟棄page_table_lock和執(zhí)行wait_split_huge_page,然后執(zhí)行舊的代碼路徑。當(dāng)wait_split_huge_page返回時(shí)候,pmd不再是巨頁的。如果pmd_trans_splitting返回false,就可以進(jìn)行處理hugepmd和hugepage。一旦完成,你可以釋放page_table_lock。
== compound_lock,get_user_pages和put_page ==
在從頁結(jié)構(gòu)清除所有PG_head/tai位之前,split_huge_page函數(shù)必須從頭頁到尾頁設(shè)置refcounts值。對(duì)huge pmd映射的refcounts很容易做到。get_page和put_page運(yùn)行在尾頁的時(shí)候(僅在尾頁),它們必須找到其各自的頭頁,
然后減少頭頁和尾頁的refcount。為了得到可靠的頭頁和在無競爭狀態(tài)下減少refcount值,put_page必須串行獲取每頁鎖compound_lock使用__split_huge_page_refcount。
compound_lock。
總結(jié)
以上是生活随笔為你收集整理的透明大页相关内核参数_透明大内存页Hugepage支持的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql begin end 用法_M
- 下一篇: oracle层级关系按列存储_几张图看懂