爲何使用巨頁?html
當一個進程使用一些內存的時候,CPU就把那部份內存標記成已被該進程使用的。爲了提升效率,CPU會按4K字節塊(它在不少平臺上是默認值)分配內存。這些塊被稱做頁。這些頁能夠被交換到磁盤上,等等。java
由於進程地址空間是虛擬的,CPU和操做系統就得記住哪一頁屬於哪一個進程,存儲在什麼地方。顯然的,擁有的頁面越多,就得花費越多的時間去尋找那些內存被映射的地方。若是一個進程使用了1GB的內存,就得查找262144(1GB/4K)個條目。若是一個頁表條目佔用8字節,那麼就得查找2MB(262144*8)。node
當前大多數CPU體系結構支持更大的頁(這樣CPU/OS要查找的條目就少了),這些頁在Linux上被稱做巨頁(Huge pages),在BSD上被稱做超級頁(Super Pages),在Windows上被稱做大頁(Large Pages),它們都是一樣的東西。mysql
目錄linux
想知道更多關於hugetlbpage的信息,請閱讀這篇文檔。sql
目前,沒有標準的方式來啓用HugeTlbfs,主要由於FHS(文件系統構架標準)中沒有這種虛擬文件系統的相關規定。參見572733。(Fedora把它掛載在/dev/hugepages上了,因此若是你在網上看到一些使用這個位置的例子,就不要驚訝了)數據庫
Debian是從DebianLenny(其實是從2.6.23)開始支持「巨頁表」(HugeTlb)的。在ibm.com上能夠找到詳細的大頁介紹。緩存
% groupadd my-hugetlbfs % getent group my-hugetlbfs my-hugetlbfs:x:2021: % adduser franklin my-hugetlbfs Adding user `franklin' to group `my-hugetlbfs' ... Adding user franklin to group my-hugetlbfs Done.
# Allocate 256*2MiB for HugePageTables (YMMV) vm.nr_hugepages = 256 # Members of group my-hugetlbfs(2021) can allocate "huge" Shared memory segment vm.hugetlb_shm_group = 2021
% mkdir /hugepages
hugetlbfs /hugepages hugetlbfs mode=1770,gid=2021 0 0
你應該配置一個用戶能夠鎖定的內存數量,這樣一個應用程序就不會經過鎖定全部內存而致使操做系統崩潰。注意並非只有巨頁能夠能夠被鎖定,內存中的任何頁面均可以被鎖定。你應該容許進程鎖定多一點的內存(只是巨頁空間)。架構
## Get huge-page size: % grep "Hugepagesize:" /proc/meminfo Hugepagesize: 4096 kB ## What's the current limit % ulimit -H -l 64 ## Just add them up... (how many pages do you want to allocate?)
參見Limits(ulimit -l 和/etc/security/limits.conf中的memlock)。less
某些架構(如ia64)能夠有多倍的和(或)可配置的(巨)頁尺寸。
(TODO)
參見:
Debian arm64 內核(用4KB標準PAGE_SIZE運行)支持2MB和1GB的 HugeTLB 頁大小。一種是在內核命令行上指定參數,從而使啓動時預分配1GB的 HugeTLB 頁面。下面的文本將預分配10*1GB的巨頁。
hugepagesz=1G hugepages=10
若是某人決定用 CONFIG_ARM64_64K_PAGES=y 來構建他本身的 Debian arm64 內核,那麼只可使用512MB的 HugeTLB(和THP)頁面。這些在運行時可用。
依據處理器,在 x86_64 架構上至少有兩種不一樣的巨頁尺寸:2MB和1GB。若是CPU支持2MB頁面,它會在cpuinfo中有 PSE 旗標;若是支持1GB頁面,它就會有 PDPE1GB 旗標。/proc/cpuinfo 顯示了是否設置了這兩種旗標。
若是下面這個命令返回非空字符串,就支持2MB頁面。
% grep pse /proc/cpuinfo | uniq flags : [...] pse [...]
若是下面這個命令返回非空字符串,就支持1GB頁面。
% grep pdpe1gb /proc/cpuinfo | uniq flags : [...] pdpe1gb [...]
若是想要兩者均可用,那麼可能須要在啓動時激活它們。下面的內核啓動參數啓用1GB頁面而且建立了一個1GB頁面池。
hugepagesz=1GB hugepages=1
在啓動後,巨頁池看起來像下面這樣:
% hugeadm --pool-list Size Minimum Current Maximum Default 2097152 0 0 0 * 1073741824 1 1 1
你能夠用hugeadm獲取到一張可用巨頁尺寸列表:
% hugeadm --page-sizes-all 2097152 1073741824
hugeadm也顯示每一個可用尺寸的已分配數量:
% hugeadm --pool-list Size Minimum Current Maximum Default 2097152 0 0 0 * 1073741824 1 1 1
另外一種獲取默認巨頁尺寸的當前可用/已用頁的方法是查看/proc/meminfo:
% grep Huge /proc/meminfo HugePages_Total: 256 HugePages_Free: 256 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 4096 kB
(想了解關於巨頁的更多信息,請閱讀文獻/vm/hugetlbpage.txt)
標準Debian內核啓用了HUGETLB(Lenny呢?Xen呢?):
% grep HUGETLB /boot/config-$(uname -r) CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y
各類運行時設置(參見文獻資料)。
% grep -R "" /sys/kernel/mm/hugepages/ /proc/sys/vm/*huge* /sys/kernel/mm/hugepages/hugepages-4096kB/nr_hugepages:256 /sys/kernel/mm/hugepages/hugepages-4096kB/nr_overcommit_hugepages:0 /sys/kernel/mm/hugepages/hugepages-4096kB/free_hugepages:256 /sys/kernel/mm/hugepages/hugepages-4096kB/resv_hugepages:0 /sys/kernel/mm/hugepages/hugepages-4096kB/surplus_hugepages:0 /proc/sys/vm/hugepages_treat_as_movable:0 /proc/sys/vm/hugetlb_shm_group:0 /proc/sys/vm/nr_hugepages:256 /proc/sys/vm/nr_overcommit_hugepages:0
體系架構 |
巨頁尺寸 |
arm64 | 4K, 2M, 1G(或者64K和512M,若是用CONFIG_ARM64_64K_PAGES=y構建本身的內核的話) |
i386 | 4M, 4M(在PAE模式下是2M) |
ia64 | 4K, 8K, 64K, 256K, 1M, 4M, 16M, 256M |
ppc64 | 4K, 16M |
libhugetlbfs庫提供了簡單的訪問巨頁內存的方式。它還包含一些用戶空間工具來提高巨頁的易用性,進行環境設置和控制等。
http://libhugetlbfs.ozlabs.org/
533708 - ITP: libhugetlbfs -- Initial package request
http://www.ibm.com/developerworks/wikis/display/LinuxP/libhuge+short+and+simple
PostgreSQL的HugeTLB(和其餘應用)非正式
http://oss.linbit.com/hugetlb/
一個應用程序能夠經過兩種不一樣的方式分配/使用HugeTlbPage:
應用程序 |
hugetlbfs |
共享內存 |
QEMU/KVM | 是 | 否 |
MySQL | 否 | 是 |
Java | 否 | 是 |
(TODO),參見:
Linux HugeTLBfs:提高MySQL數據庫應用程序性能
http://www.cyberciti.biz/tips/linux-hugetlbfs-and-mysql-performance.html (未測試)
Sun和OpenJDK可使用大頁。
(TODO)
總的來講,要啓用巨頁,彷佛得使用 -XX:+UseLargePages 選項運行java。Java堆(-Xmx)的上限尺寸應該能夠容納你預留的巨頁;使用 ulimit -l 和/或 /etc/security/limits.conf 中的memlock。
參見:
可能的錯誤:
% java -XX:+UseLargePages Java HotSpot(TM) Server VM warning: Failed to reserve shared memory (errno = 1). Java HotSpot(TM) Server VM warning: Failed to reserve shared memory (errno = 22).
memcached可以使用巨頁,請閱讀手冊頁:
嘗試使用大內存頁(若是可用)。增長內存頁尺寸能夠減小TLB漏掉的數量,並提高性能。爲了從操做系統裏獲取大頁,memcached將會把全部的條目緩存分配到一個大頁塊中。只有你的操做系統支持大頁的時候纔可用。
PostgreSQL 從版本9.4開始支持巨頁。關於以前的版本,參見上面的hugetlblib。
巨頁虛擬化的一些建議:
(TODO),參見:
(TODO)
Xen從哪一個版本開始支持巨頁,還有它如何使用,都不是很清楚。
說明:本文譯自https://wiki.debian.org/Hugepages。因爲英語水平有限,語句不通順處還請諒解。