代碼大頁(Huge Pages)是基於透明大頁THP(Transparent Huge Pages)進行的最佳化擴充,支援將應用程式和動態連結程式庫的可執行部分放入到大頁(通常是2 MB或更大)中,有助於降低程式的iTLB miss,並提升CPU的2 MB iTLB利用率,避免記憶體片段化或記憶體膨脹問題,提高記憶體利用效率,適用於資料庫、大型應用程式等大程式碼片段業務情境。本文主要介紹代碼大頁的使用方法以及效能收益等。
根據實際的使用經驗,代碼大頁在不同平台效能提升不同,具體與應用本身的執行方式有關。
有關代碼大頁中一些常用名詞解釋,請參見附錄:名詞解釋。
使用限制
僅以下核心版本的Alibaba Cloud Linux鏡像支援使用代碼大頁功能:
Alibaba Cloud Linux 2:
4.19.91-25
及以上核心版本。Alibaba Cloud Linux 3:
5.10.112-11
及以上核心版本。
您可以通過uname -r
命令查詢鏡像的核心版本。
使用代碼大頁
啟用代碼大頁
該功能預設是關閉的,可以使用sysfs
介面進行啟用。支援如下三種啟用方式。
方式一:僅開啟二進位和動態庫大頁
sudo sh -c 'echo 1 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
方式二:僅開啟可執行匿名大頁
sudo sh -c 'echo 2 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
方式三:同時開啟以上兩類大頁
sudo sh -c 'echo 3 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
開啟代碼大頁功能並不意味著立即合并大頁,代碼大頁功能是非同步。
檢查是否啟用代碼大頁
運行以下命令,查看/proc/<pid>/smaps中的FilePmdMapped
欄位可確定是否使用了代碼大頁,FilePmdMapped
欄位表示進程代碼大頁的使用數量(單位kB)。
sudo cat /proc/<pid>/smaps | grep FilePmdMapped | awk '{sum+=$2}END{print"Sum= ",sum}'
<pid>
需替換為您實際應用程式進程ID,可通過pidof sshd
查看進程ID。
關閉代碼大頁
運行以下命令,使用sysfs
介面關閉代碼大頁。
sudo sh -c 'echo 0 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
關閉代碼大頁功能並不意味著立即拆散大頁,代碼大頁功能是非同步。
如果一段代碼曾經被合并為大頁,即使關閉代碼大頁功能,大頁緩衝還是存在。
另外,支援在系統啟動項中設定代碼大頁的狀態:設定hugetext=0/1/2/3。系統啟動項與您系統的GRUB版本以及系統鏡像有關,請您根據實際情況進行配置。
關閉代碼大頁後,同時支援以下幾種方式清理已使用的大頁。
方式一:清理整個系統的page cache(檔案快取)
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
方式二:清理單個檔案的page cache(檔案快取)
sudo vmtouch -e /<path>/target
說明vmtouch是一個用於檢查檔案是否已經載入到記憶體中,並且可以將檔案鎖定到記憶體或者從記憶體中卸載的工具。如果您沒有安裝vmtouch,需先執行
sudo yum install vmtouch
命令安裝。<path>
需替換為您實際應用程式的檔案路徑。
方式三:清理遺留大頁
sudo sh -c 'echo 1 > /sys/kernel/debug/split_huge_pages'
效能收益
該功能在不同平台最佳化效果不同,主要原因在於平台轉譯後備緩衝器TLB(Translation Lookaside Buffer)模組的設計。當前已知較適用情境包括資料庫類業務(例如MySQL、PostgreSQL等)和Java類業務,物理機上最佳化效果約為5%~8%,虛擬機器環境收益更佳。下面以MySQL為例,驗證Arm平台上代碼大頁的效能收益。
如果一段代碼曾經被合并為大頁,即使關閉代碼大頁功能,大頁緩衝還是存在。所以在測試效能時建議通過echo 3 > /proc/sys/vm/drop_caches
清理系統的大頁緩衝,以確保效能測試的準確性。
假設vCPU總核心數為32,測試過程中MySQL並發數分別是1、8(25%)、16(50%)、32(100%)。2 MB代碼大頁與普通4 KB字碼頁效能指標TPS(Transaction Per Second)資料對比如下:
通過上圖TPS資料對比可以看出,代碼大頁的效能始終高於普通字碼頁。詳細說明如下:
並發數為1時,外在的影響因素較小。此時代碼大頁相比普通字碼頁,效能提升大約6.9%。
並發數為8、16時,基本可以保證沒有CPU的競爭,代碼大頁的效能提升大約也在6.5%以上。
並發數為32時,可能存在其他應用競爭CPU,所以TPS較低於前面的測試結果。在系統受到不確定因素擾動時,代碼大頁的穩定性更好,此時相比普通字碼頁,效能提升大約11%左右。
上圖展示的是代碼大頁與普通4 KB字碼頁的iTLB資料,左圖是iTLB miss資料,右圖是iTLB MPKI資料。MySQL使用代碼大頁後:
iTLB miss大約下降了10倍左右,數值大小從原來的0.09%左右下降到0.08%左右。
iTLB MPKI大約下降了6倍左右。
除MySQL外,代碼大頁在PostgreSQL上也存在7%左右的效能提升。
Padding功能
Padding功能是對代碼大頁特性的最佳化,主要解決應用載入後的程式碼片段未完全使用代碼大頁導致的不是最佳效能效果(未使用代碼大頁部分屬於熱點)的問題。該特性需要在啟用代碼大頁的基礎上使用,不可獨立使用。例如,當二進位檔案末尾剩餘text段由於不足2 MB而無法使用大頁時,當剩餘text大小超過hugetext_pad_threshold
值,可將其填充為2MB text,保證可使用上大頁。
啟用Padding
運行以下命令,使用
sysfs
介面啟用Padding功能。sudo sh -c 'echo [0~2097151] > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
說明建議一般情況寫4096即可,即
sudo sh -c 'echo 4096 > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
。一般情況下,應用的程式碼片段映射地址一般是2MB對齊(代碼大頁同時也做了地址對齊的最佳化),但緊跟的rw-p或r--p部分不一定為2 MB對齊,這種情況可能會導致
hugetext_pad_threshold
不能理想填充,存在部分程式碼片段使用4 KB頁。建議您在使用Padding功能時,將程式碼片段和資料區段2 MB對齊。對齊方法:修改預設的lds檔案,在代碼和資料區段前加上. = ALIGN(0x200000);
即可。關閉Padding
運行以下命令,使用
sysfs
介面關閉Padding功能。sudo sh -c 'echo 0 > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
附錄:名詞解釋
代碼大頁功能中一些常用名詞解釋如下所示。
名詞 | 說明 |
大頁 | 大頁(HugePages),也稱為大記憶體頁。是指作業系統以大於4 KB的頁大小為嵌入式管理單元的一種記憶體配置和管理方式,大頁可以提高硬體TLB利用率進而提升效能。 |
透明大頁 | 透明大頁(Transparent Huge Pages)是一種隱式使用大頁的方式,在使用者進程無感知的情況下,系統後台通過啟動核心線程非同步掃描每一個進程的虛擬位址空間,整合合適的虛擬位址空間VMA(Virtual Memory Area)為2 MB大頁。 |
代碼大頁 | 代碼大頁(Hugetext)利用透明大頁相同的整合機制,僅將代碼部分整合為大頁,效能提升效果明顯。 |
iTLB miss | 指令轉換後備緩衝區iTLB(Instruction Translation Lookaside Buffer)的不命中率,iTLB命中率低,會導致CPU無法高效運行。 |
iTLB利用率 | 指令轉換後備緩衝區iTLB的利用率,利用率越高,系統的效能越高。 |
iTLB MPKI | 指令轉換後備緩衝區iTLB中每千條指令的未命中資料,未命中資料越小,系統的效能越高。 |
相關文檔
Alibaba Cloud Linux系統也可以通過透明大頁提高記憶體訪問的效率。透明大頁可以自動將小頁面(通常為4 KB)合并成大頁面(通常為2 MB或更大),可以減少記憶體訪問頁表項PTE(Page Table Entries)大小和訪問次數,從而減輕TLB緩衝的壓力提升程式效能。更多資訊,請參見Alibaba Cloud Linux系統中與透明大頁THP相關的效能調優方法。