[翻譯]-hugePage的簡要說明--部分內容

hugePage的簡要說明

本篇文檔的主旨給linux內核支持的大頁內存做一個簡要的概述. 
大頁內存的實現是建立在大多數現代架構所都支持的多級頁大小的特性之上的. 
舉例: x86架構下大部署CPU 的頁面大小是4KB 或者是 2MB. 部分新的CPU支持1GB的頁面大小. 
      IA64的架構支持 4K, 8K, 64K, 256K, 1M, 4M, 16M, 256M
      PPC64的架構支持: 4K 16MB
TLB是一個很小又很珍貴的資源, 主要用於快速實現虛擬內存到物理內存的專用工作. 
現代操作系統很關鍵的一個優化項目就在於隨着內存的越來越大, 要更好的利用TLB以提高性能

用戶可以使用mmap或者是shmget, shmat 這種基於標準的SYSV共享內存機制來使用大頁內存. 

首先: linux的內核需要增加CONFIG_HUGETLBFS和CONFIG_HUGETLB_PAGE的配置項目.
      (其中CONFIG_HUGETLB_PAGE會因爲CONFIG_HUGETLBFS的設置而自動生效)
/proc/meminfo 文件提供了系統內核裏面大頁內存池的詳細信息. 
並且還會實時顯示系統內核裏面的大頁的大小,以及空閒,佔用了的,以及過量申請的的大頁數量. 
大頁內存的使用是需要使用帶合適參數的系統調用以便映射到大頁區域的. 

一般情況下/proc/meminfo 的戰事信息主要如下: 
HugePages_Total: uuu
HugePages_Free:  vvv
HugePages_Rsvd:  www
HugePages_Surp:  xxx
Hugepagesize:    yyy kB
Hugetlb:         zzz kB

其中: 
HugePages_Total 大頁內存的總量
HugePages_Free  沒有被分配的大頁內存數量.
HugePages_Rsvd  系統當前總共保留的大頁數目,具體點是指程序已經向系統申請,但是還沒有具體執行寫入
                表示爲尚未實際分配給程序的HugePages數目。
HugePages_Surp  超過設定的大頁內存的數量. 
Hugepagesize    大頁內存的單獨每個頁面的大小.
Hugetlb         大頁內存的總計大小,單位爲KB 可以理解爲 Hugepagesize*HugePages_Total

/proc/filesystems  也會描述一個在內核中進行配置了的大頁內存文件系統. 
/proc/sys/vm/nr_hugepages 指代Linux內核裏面持久化大頁內存頁面多少
只有root用戶權限纔可以增加或者是改參數值的大小. 

只要是內存已經保留了大頁內存的頁面就不會因爲內存壓力還進入swap內存區域. 
並且大頁內存不會用於非大頁內存的使用場景, 是專用的. 
設置了大頁內存後,用戶可以使用合適的權限通過mmap後者是shmget等方式進行申請大頁內存的使用

建議在系統啓動時就直接修改好hugepages=N 的參數,  避免如果長時間使用導致內存隨便無法申請足夠打的大頁內存. 
很多平臺支持多種大小的內存頁大小. 如果想使用其他大小的大頁內存頁大小, 需要在啓動的參數中增加:
default_hugepagesz=<size> 的參數纔可以, 這個參數需要使用精確的字節大小, 可以使用[kKmMgG] 作爲後綴

/proc/sys/vm/nr_hugepages 裏面其實使用的是默認的頁大小. 並且是支持動態修改的, 可以使用如下命令來動態修改:
echo 20 > /proc/sys/vm/nr_hugepages
該命令會盡力在系統中申請20個大頁內存. 用於進行分配和使用. 

需要注意在NUMA系統的情況時: 內核會嘗試在所有的numa節點都平均分佈大頁的設置. 
這一塊可能在單一numa節點內存不足時出現很多問題. 文章後面有一些詳細的討論
(看不太懂 -- 這句不是我說的 不是原文. )

是否能夠成功申請到大頁內存取決於系統上在申請大頁內存的時刻是否有連續的並且可用的空閒內存. 
如果內核無法在一個numa節點上面申請到一個足夠的內存. 會嘗試從其他節點進行內存申請. 

系統管理員一般都喜歡在啓動啓動時就可以自動執行內存申請的命令.
可以設置爲 local rc init files 實現自動加載. 
並且可以通過如下命令來查看不同numa節點的內存大頁使用情況
cat /sys/devices/system/node/node*/meminfo | fgrep Huge

/proc/sys/vm/nr_overcommit_hugepages 
該參數會嘗試再使用了nr_hugepages 以上的內存
如果設置了非零數值, 系統耗盡了 nr_hugepages 的內存之後 會嘗試繼續申請 非零數值的內存
但是需要注意, 如果這些內存被釋放了, 也會反饋給內核,將大頁內存的限制取消, 會繼續正常分配內存. 
如果的確有需求申請大約持久的大頁內存的數值, 建議直接修改nr_hugepages 的大小.對性能會更好一些. 

管理員也可以通過減少nr_hugepages 的數值來減少凍結的大頁內存數量. 並且設置完之後內核會自動在
不同的numa節點上的空閒內存釋放出來便於其他非大頁內存使用. 

另外 /proc的文件系統與/sys下面是有一些對應的. 
比如 :/sys/kernel/mm/hugepages
hugepages-${size}kB
其實還有一些其他參數也在統計目錄下面, 比如:
	nr_hugepages
	nr_hugepages_mempolicy
	nr_overcommit_hugepages
	free_hugepages
	resv_hugepages
	surplus_hugepages
這些參數會展示很多內核關於大頁內存的默認值信息. 

任務內存管理側率與大頁內存申請和凍結的交互

申請或者是凍結內存的策略可以通過修改/proc虛擬文件系統和/sysfs文件系統的 nr_hugepages_mempolicy 參數來實現
但是需要注意如果啓用了 nr_hugepages 的參數 nr_hugepages_mempolicy 的參數就會被忽略

我不想翻譯這一段了, 自己看原文吧. 我不想用這個參數..網上都木有, 感覺容易掉坑裏. 


每個numa節點的大頁內存屬性

/sysfs下面有一個基於大頁內存控制上, 針對每一個numa節點的子節點內容
他具體體現在如下的設備內存信息中
/sys/devices/system/node/node[0-9]*/hugepages/

並且與系統級的大頁內存設置相仿,也有如下的配置屬性信息

	nr_hugepages
	free_hugepages
	surplus_hugepages

nr 和 free 與系統級的參數含義相仿. 
但是surplus 時當前節點沒有可用的連續內存時, 系統會嘗試從其他numa節點申請內存. 

使用大頁內存

如果應用程序希望使用mmap的系統調用來申請大頁內存
需要系統管理員 mount 一個 hugetlbfs 的文件類型. 
  mount -t hugetlbfs \
	-o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,\
	min_size=<value>,nr_inodes=<value> none /mnt/huge

這個命令會在/mnt/huge 目錄下掛載一個虛擬的hugetlbfs類型的文件系統
任何在這個目錄上創建的文件 文件權限默認值是  01777 
mmap的使用比較高深. 單詞我都明白, 但是我嘗試翻譯了好幾次,翻譯不好, 請看原文吧..

This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
/mnt/huge.  Any files created on /mnt/huge uses huge pages.  The uid and gid
options sets the owner and group of the root of the file system.  By default
the uid and gid of the current process are taken.  The mode option sets the
mode of root of file system to value & 01777.  This value is given in octal.
By default the value 0755 is picked. If the platform supports multiple huge
page sizes, the pagesize option can be used to specify the huge page size and
associated pool.  pagesize is specified in bytes.  If pagesize is not specified
the platform's default huge page size and associated pool will be used. The
size option sets the maximum value of memory (huge pages) allowed for that
filesystem (/mnt/huge).  The size option can be specified in bytes, or as a
percentage of the specified huge page pool (nr_hugepages).  The size is
rounded down to HPAGE_SIZE boundary.  The min_size option sets the minimum
value of memory (huge pages) allowed for the filesystem.  min_size can be
specified in the same way as size, either bytes or a percentage of the
huge page pool.  At mount time, the number of huge pages specified by
min_size are reserved for use by the filesystem.  If there are not enough
free huge pages available, the mount will fail.  As huge pages are allocated
to the filesystem and freed, the reserve count is adjusted so that the sum
of allocated and reserved huge pages is always at least min_size.  The option
nr_inodes sets the maximum number of inodes that /mnt/huge can use.  If the
size, min_size or nr_inodes option is not provided on command line then
no limits are set.  For pagesize, size, min_size and nr_inodes options, you
can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For example, size=2K
has the same meaning as size=2048.

While read system calls are supported on files that reside on hugetlb
file systems, write system calls are not.

Regular chown, chgrp, and chmod commands (with right permissions) could be
used to change the file attributes on hugetlbfs.

Also, it is important to note that no such mount command is required if
applications are going to use only shmat/shmget system calls or mmap with
MAP_HUGETLB.  For an example of how to use mmap with MAP_HUGETLB see map_hugetlb
below.

Users who wish to use hugetlb memory via shared memory segment should be a
member of a supplementary group and system admin needs to configure that gid
into /proc/sys/vm/hugetlb_shm_group.  It is possible for same or different
applications to use any combination of mmaps and shm* calls, though the mount of
filesystem will be required for using mmap calls without MAP_HUGETLB.

Syscalls that operate on memory backed by hugetlb pages only have their lengths
aligned to the native page size of the processor; they will normally fail with
errno set to EINVAL or exclude hugetlb pages that extend beyond the length if
not hugepage aligned.  For example, munmap(2) will fail if memory is backed by
a hugetlb page and the length is smaller than the hugepage size.

參考資料

1) map_hugetlb: see tools/testing/selftests/vm/map_hugetlb.c

2) hugepage-shm:  see tools/testing/selftests/vm/hugepage-shm.c

3) hugepage-mmap:  see tools/testing/selftests/vm/hugepage-mmap.c

4) The libhugetlbfs (https://github.com/libhugetlbfs/libhugetlbfs) library
   provides a wide range of userspace too
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章