【Debian百科】巨頁

巨頁

爲何使用巨頁?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

  1. 啓用HugeTlbPage
  2. limits.conf
  3. Multiple huge page size support
    1. arm64
    2. x86_64
  4. 獲取信息
  5. 巨頁大小
  6. 工具
  7. 支持巨頁的應用
    1. MySQL
    2. Java(Sun, OpenJDK)
    3. Memcached
    4. PostgreSQL
  8. 虛擬化
  9. 參見

想知道更多關於hugetlbpage的信息,請閱讀這篇文檔。sql

啓用HugeTlbPage

目前,沒有標準的方式來啓用HugeTlbfs,主要由於FHS(文件系統構架標準)中沒有這種虛擬文件系統的相關規定。參見572733。(Fedora把它掛載在/dev/hugepages上了,因此若是你在網上看到一些使用這個位置的例子,就不要驚訝了)數據庫

Debian是從DebianLenny(其實是從2.6.23)開始支持「巨頁表」(HugeTlb)的。在ibm.com上能夠找到詳細的大頁介紹。緩存

  1. 建立一個巨頁的用戶組,而且獲取它的GID(是這個例子,2021),而後把你本身添加到這個組裏。
    注意:libvirt並不須要這樣作。(參見/etc/libvirt/qemu.conf)
    % 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. 
  2. 編輯/etc/sysctl.conf,添加這個文原本指定你想要預留的頁數(參見pages-size)。
    # 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 
  3. 給這個文件系統建立一個掛載點。
    % mkdir /hugepages
  4. 添加這一行代碼到/etc/fstab(mode=1770准許組內的任何人建立文件,可是不能給彼此之間的文件解除連接或者重命名)。
    hugetlbfs /hugepages hugetlbfs mode=1770,gid=2021 0 0
  5. 重啓(這是再內存碎片化以前分配巨頁的最可靠方法。並非必需要重啓,你能夠嘗試執行 sysctl -p 來應用變化。若是 grep "Huge" /proc/meminfo 沒有顯示全部頁面,你能夠嘗試執行 sync ; echo 3 > /proc/sys/vm/drop_caches (3表示清除頁面緩存,dentries和inodes)來釋放緩存,而後再次嘗試執行 sysctl -p)。

limits.conf

你應該配置一個用戶能夠鎖定的內存數量,這樣一個應用程序就不會經過鎖定全部內存而致使操做系統崩潰。注意並非只有巨頁能夠能夠被鎖定,內存中的任何頁面均可以被鎖定。你應該容許進程鎖定多一點的內存(只是巨頁空間)。架構

## 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

Multiple huge page size support

某些架構(如ia64)能夠有多倍的和(或)可配置的(巨)頁尺寸。

(TODO)

參見:

  • 文件編制中的 hugetlbpage.txt 中的啓動參數和掛載選項。

arm64

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

依據處理器,在 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:

  1. 擁有適當的權限下,掛載了hugetlbfs後,使用系統調用mmap;
  2. 共享內存段(在MAP_TLB環境下使用系統調用shmat/shmget或者mmap)必須是一個組成員,配置在/proc/sys/vm/hugetlb_shm_group。

應用程序

hugetlbfs

共享內存

QEMU/KVM
MySQL
Java

MySQL

(TODO),參見:

Linux HugeTLBfs:提高MySQL數據庫應用程序性能

http://www.cyberciti.biz/tips/linux-hugetlbfs-and-mysql-performance.html (未測試)

Java(Sun, OpenJDK)

Sun和OpenJDK可使用大頁。

(TODO)

總的來講,要啓用巨頁,彷佛得使用 -XX:+UseLargePages 選項運行java。Java堆(-Xmx)的上限尺寸應該能夠容納你預留的巨頁;使用 ulimit -l 和/或 /etc/security/limits.conf 中的memlock。

參見:

  1. 大內存頁的Java支持 - Sun:http://java.sun.com/javase/technologies/hotspot/largememory.jsp
  2. 大頁內存分配的配置 - Linux上的 Java v6 的 IBM 用戶指南:http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=/com.ibm.java.doc.user.lnx.60/user/alloc_large_page.html

可能的錯誤:

  • 功能不全的 /proc/sys/kernel/shmmax?
  • 不在組中卻定義在 /proc/sys/vm/hugetlb_shm_group
% 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

memcached可以使用巨頁,請閱讀手冊頁:

memcached -L

嘗試使用大內存頁(若是可用)。增長內存頁尺寸能夠減小TLB漏掉的數量,並提高性能。爲了從操做系統裏獲取大頁,memcached將會把全部的條目緩存分配到一個大頁塊中。只有你的操做系統支持大頁的時候纔可用。

PostgreSQL

PostgreSQL 從版本9.4開始支持巨頁。關於以前的版本,參見上面的hugetlblib

虛擬化

巨頁虛擬化的一些建議:

  1. 在虛擬機上啓用巨頁以前,你必須確保你的虛擬化工具能夠處理它;
  2. 對於虛擬化工具來講,它的客戶端是否支持巨頁,和它自己是否支持巨頁,多是兩個不一樣的方面。

KVM

(TODO),參見:

Xen

(TODO)

Xen從哪一個版本開始支持巨頁,還有它如何使用,都不是很清楚。

 


說明:本文譯自https://wiki.debian.org/Hugepages。因爲英語水平有限,語句不通順處還請諒解。

相關文章
相關標籤/搜索