6 ヒュージ・ページの構成
Oracle Linuxでは、物理メモリーはページと呼ばれる固定サイズのブロックで管理されます。x86_64アーキテクチャでは、各ページのデフォルト・サイズは4KBです。
カーネルは、ページの仮想アドレスから物理アドレスへのマッピングを、ページ表と呼ばれるデータ構造に格納します。ただし、ページ表のルックアップはリソースを大量に消費するため、最近使用されたアドレスはCPUのTranslation Lookaside Buffer (TLB)にキャッシュされるため、取得が高速になります。CPUがアドレスマッピングのリクエストを満たす必要がある場合、CPUは最初にそのTLBキャッシュを検索します。TLBヒットは、TLBキャッシュ内のアドレスを見つけるCPUを示します。TLBミスは、リクエストされたアドレスマッピングがキャッシュ内に見つからないCPUを示します。その場合、システムはページ表上でリソースを大量に消費するルックアップを実行してアドレス情報を取得します。
4KBのデフォルト・ページ・サイズは、ほとんどのアプリケーションに適しています。ただし、大量のメモリーで動作するアプリケーションの場合、必要な4KBページの数が増加し、TLBミスの数が多くなり、パフォーマンスのオーバーヘッドが発生する可能性があります。より多くのメモリーを必要とするアプリケーションがより少ないページで要件を満たすことができるように、Oracle Linuxにはヒュージ・ページ機能が提供されています。
使用可能なヒュージ・ページ機能
Oracle Linuxには、次のヒュージ・ページ機能が含まれています:
HugeTLBページ
HugeTLBページは、静的ヒュージ・ページとも呼ばれます。
HugeTLBページ機能を使用すると、各ヒュージ・ページのサイズについて、指定された各数量のヒュージ・ページのプールを予約できます。x86_64プラットフォームで使用可能な巨大なページ・サイズ・オプションは、2MBおよび1GBです。
ノート:
ベスト・プラクティス:- メモリーの断片化の発生が最小限の場合、できるだけブート時間に近い静的なヒュージ・ページのリクエストをカーネルに作成します。
- ヒュージ・ページでは、システムで使用可能なメモリーの量を減らすことができます。したがって、予約されたヒュージ・ページ・プールをリクエストする場合は、プールのサイズが超過していないこと、およびシステムのメモリーへのアクセスが影響を受けないことを確認してください。
透過的HugePages
透過的HugePages (THP)機能は、Oracle Linuxでデフォルトで有効になっています。THPでは、カーネルによってヒュージ・ページが自動的にプロセスに割り当てられます。THPでは、x86_64プラットフォームに2MBのページのみを割り当てることができます。
THPは、次のモードで実行できます。
system-wide
(デフォルト): カーネルは、可能なかぎり、連続する大きな仮想メモリー領域を使用するプロセスにヒュージ・ページを割り当てます。per-process:
カーネルは、madvise()
システム・コールを介してヒュージ・ページを明示的にリクエストするアプリケーション・プロセスにのみ、ヒュージ・ページを割り当てます。
THPの構成の詳細は、「透過的HugePagesの構成」を参照してください
HugeTLBページの構成
次のタイプのパラメータを使用して、HugeTLBページを構成できます。
- カーネル・ブート・パラメータ
- ファイルベースの構成パラメータ
次の各項では、パラメータの詳細を説明します。
HugeTLBページのカーネル・ブート・パラメータ
カーネル・ブート・オプションを使用すると、カーネルのプールに予約するサイズやページ数などの値を指定できます。カーネル・ブート・パラメータの使用は、ヒュージ・ページをリクエストする最も信頼性の高い方法です。
表6-1 HugeTLBページをリクエストするためのカーネル・ブートのコマンドライン・パラメータ
<table cellpadding="4" cellspacing="0" class="Formal" title="The Kernel Boot Command Line Parameters for Requesting HugeTLB Pages" summary='This table describes the kernel boot parameters that are available for HugeTLB page setup. The content includes variable placeholders, for example "<size>" for size of page, and "default_hugepagesz
2M
(デフォルト)、1G
hugepagesz
およびhugepages
サイズ・パラメータhugepagesz
を数量パラメータhugepages
とともに使用して、指定したページ・サイズおよび数量のプールを予約します。たとえば、サイズが2MBの1500ページのプールをリクエストするには、コマンドライン・オプションは次のようになります:
hugepagesz=2M hugepages=1500
複数のヒュージ・ページ・サイズがサポートされている場合は、ページ・サイズごとに1回ずつ、"hugepagesz=<size> hugepages=<qty>
"ペアを複数回指定できます。たとえば、次のコマンドライン・オプションを使用すると、1GBサイズの4ページの1つのプールと、2MBサイズの1500ページのもう1つのプールをリクエストできます:
hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1500
Hugepagesz
: 2M
、1G
hugepages
: 0
以上
ノート:
NUMAシステムでは、前の表に示すように、カーネル・コマンドライン・オプションで予約されたページはNUMAノード間で均等に分割されます。各ノードでページ数が異なることが要件である場合は、sysfs
ファイル・システムでファイルベースのHugeTLBパラメータを使用できます。「HugeTLBページのファイルベースの構成パラメータ」および「ブート・プロセスの初期段階でのNUMAノード固有パラメータを使用したHugeTLBページのリクエスト」を参照してください。
HugeTLBページのファイルベースの構成パラメータ
ノート:
実行時に設定にアクセスするだけでなく、起動bashスクリプトの作成や、ローカルのrc initスクリプトでのパラメータの設定によって、ブート・プロセスの初期段階でパラメータを初期化することもできます。nr_hugepages
設定が存在することが可能です。このパラメータは、次のようなプール内のページ数を定義します:
- 2MBページのプール内のページ数を示すファイル
/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
。 - 1GBページのプール内のページ数を示すファイル
/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
。
次の表に、一般的に使用されるHugeTLB構成パラメータと、各パラメータに対して検出される複数のファイル・インスタンスを示します。
表6-2 一般的に使用されるファイルベースのHugeTLBパラメータ
<table cellpadding="4" cellspacing="0" class="Formal" title="Commonly Used File-Based HugeTLB Parameters" summary='This table outlines commonly used HugeTLB configuration parameters and the multiple file instances that you might find for each parameter. Some folders in the parameter file paths are listed with placeholder names that convey a range of possible values. For example, the folder name “hugepages-nr_hugepages
nr_hugepages
の各インスタンスは、そのインスタンスに関連付けられたプール内の現在のヒュージ・ページ数を定義します。- 実行時に変更できます。
-
コマンド例:
echo 20 | sudo tee /proc/sys/vm/nr_hugepages
- デフォルト値は
0
です。
nr_hugepages
の異なるインスタンスのファイル・パス形式は次のとおりです。
- ファイルの場所:
/proc/sys/vm/nr_hugepages
(すべてのシステムに存在)。 - ファイルの場所:
/sys/kernel/mm/hugepages/hugepages-<SIZE>kB/nr_hugepages
(複数のヒュージ・ページ・サイズをサポートするシステム上に存在)。 -
ファイルの場所:
/sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/nr_hugepages
(NUMAシステムのみに存在)。ノート:
特定のNUMAノードでサポートされる様々なサイズのページ数をリクエストする必要がある場合は、NUMAノード固有のパス形式を使用します。他のパス形式(
/proc/sys/vm/nr_hugepages
など)を使用する場合は、HugeTLBページをリクエストします。ページはNUMAノード間で均等に分割されます。
nr_overcommit_hugepages
nr_overcommit_hugepages
の各インスタンスは、nr_hugepages
で指定された数量より多い追加の数のヒュージ・ページを定義します。これは、メモリーのオーバーコミットを通じて実行時に、システムによって作成されます。- これらの追加のヒュージ・ページは、使用されなくなると、解放されてカーネルの通常のページ・プールに戻されます。
- コマンド例:
echo 20 | sudo tee /proc/sys/vm/nr_overcommit_hugepages
nr_overcommit_hugepages
の異なるインスタンスのファイル・パス形式は次のとおりです。
- ファイルの場所:
/proc/sys/vm/nr_overcommit_hugepages
(すべてのシステムに存在)。 - ファイルの場所:
/sys/kernel/mm/hugepages/hugepages-<SIZE>kB/nr_overcommit_hugepages
(複数のページ・サイズをサポートするシステムに存在)。
ノート:
nr_overcommit_hugepages
パラメータは個々のノード・レベルでは定義されないため、この設定にはノード固有のファイルが存在しません。
free_hugepages
- 読取り専用パラメータ。
free_hugepages
の各インスタンスは、まだ割り当てられていない関連ページ・プール内のヒュージ・ページ数を返します。
free_hugepages
の異なるインスタンスのファイル・パス形式は次のとおりです。
- ファイルの場所:
/sys/kernel/mm/hugepages/hugepages-<SIZE>kB/free_hugepages
(複数のヒュージ・ページ・サイズをサポートするシステム上に存在)。 - ファイルの場所:
/sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/ free_hugepages
(NUMAシステムのみに存在)。
surplus_hugepages
- 読取り専用パラメータ。
surplus_hugepages
の各インスタンスは、関連付けられたページ・プールからオーバーコミットされたヒュージ・ページ数を返します。
surplus_hugepages
の異なるインスタンスのファイル・パス形式は次のとおりです。
- ファイルの場所:
/sys/kernel/mm/hugepages/hugepages-<SIZE>kB/surplus_hugepages
(複数のヒュージ・ページ・サイズをサポートするシステムに存在)。 - ファイルの場所:
/sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/surplus_hugepages
(NUMAシステムのみに存在)。
次の項では、HugeTLBパラメータの様々なインスタンスが格納されるファイルのブランチを示します:
/proc/sys/vm
静的ヒュージ・ページをサポートするすべてのシステムには、/proc/sys/vm
の下にHugeTLBパラメータ・ファイルが含まれています。
ノート:
多数のOracleデータベース・サーバーを含む多くのシステムでは、procfs
ファイル・システムが使用される主要なパラメータ・セットです。
sysctl
パラメータvm.nr_hugepages
は、通常、ヒュージ・ページをリクエストするスクリプトで初期化され、procfs
ファイル/proc/sys/vm/nr_hugepages
にも書き込まれます。
ブランチ/proc/sys/vm
の下にあるフォルダの例を次に示します:
├── ...
├── ...
├── nr_hugepages
├── ...
├── nr_overcommit_hugepages
├── ...
├── ...
/sys/kernel/mm/hugepages/
複数のサイズ・プールをサポートするシステムには、/sys/kernel/mm/hugepages/
のサイズ固有のフォルダにHugeTLBパラメータ・ファイルが含まれています。
ブランチ/sys/kernel/mm/hugepages/
の下にあるフォルダの例を次に示します:
└── hugepages-2048kB
├── free_hugepages
├── nr_hugepages
├── ...
├── nr_overcommit_hugepages
├── ...
└── surplus_hugepages
└── hugepages-1048576kB
├── free_hugepages
├── nr_hugepages
├── ...
├── nr_overcommit_hugepages
├── ...
└── surplus_hugepages
/sys/devices/system/node/
NUMAシステムのみに、/sys/devices/system/node/
にHugeTLBパラメータ・ファイルが含まれています。
ブランチ/sys/devices/system/node
の下にあるフォルダの例を次に示します:
├─ ...
├── node0
│ ├── ...
│ ├──hugepages
│ hugepages-2048kB
│ ├── free_hugepages
│ ├── nr_hugepages
│ └── surplus_hugepages
│
│ hugepages-1048576kB
│ ├── free_hugepages
│ ├── nr_hugepages
│ └── surplus_hugepages
├── node1
├── ...
├──hugepages
hugepages-2048kB
├── free_hugepages
├── nr_hugepages
└── surplus_hugepages
hugepages-1048576kB
├── free_hugepages
├── nr_hugepages
└── surplus_hugepages
ブート時のHugeTLBページの構成
ブート時にヒュージ・ページをリクエストする詳細な方法は、システムの要件によって異なります。次の手順の例では、使用可能な開始点について説明します。
ブート時のカーネル・パラメータを使用したHugeTLBページのリクエスト
- 1GBのデフォルトのページ・サイズ。
- 1GBサイズのHugeTLBページが4つ含まれる1つのプール。
- 2MBサイズの1500のHugeTLBページが含まれる1つのプール。
- カーネル・ブート・パラメータ
default_hugepagesz
に1GBサイズを指定し、2つのヒュージ・ページ・プールに2つのペアの"hugepagesz=<Size_num>G hugepages=Qty_num
"パラメータを指定します。/etc/default/grub
のカーネル・コマンドライン・オプションに次の行を追加しますdefault_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1500
GRUB2
構成ファイルを再生成します。- システムでBIOSファームウェアを使用している場合、次のコマンドを実行します:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
- システムでUEFIフレームワークを使用している場合、次のコマンドを実行します:
sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
- システムでBIOSファームウェアを使用している場合、次のコマンドを実行します:
- 次回システムがブートすると、2つのヒュージ・ページ・プールがリクエストされます。
ブート・プロセスの初期段階でのNUMAノード固有パラメータを使用したHugeTLBページのリクエスト
前述の例に示すように、カーネル・ブート時パラメータを使用してリクエストされたヒュージ・ページは、NUMAノード間で均等に分割されます。
ただし、ノード固有のファイル・パスに構成値を設定して、特定のノードに対して異なる数のヒュージ・ページをリクエストすることが必要になる場合があります。ファイル・パスは次のように定義されます:
/sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/
次の手順では、NUMAシステムのノード0に2MBサイズの299ページと、ノード1に2MBサイズの300ページを予約する方法について説明します。
次の手順を開始する前に、すべてのステップに必要な管理権限があることを確認してください。
/usr/lib/systemd/
ディレクトリにhugetlb-reserve-pages.sh
というスクリプト・ファイルを作成し、次の内容を追加します。#!/bin/sh nodes_path=/sys/devices/system/node/ if [ ! -d $nodes_path ]; then echo "ERROR: $nodes_path does not exist" exit 1 fi ####################################################### # # # FUNCTION # # reserve_pages <number_of_pages> <node_id> # # # ####################################################### reserve_pages() { echo $1 > $nodes_path/$2/hugepages/hugepages-2048kB/nr_hugepages } reserve_pages 299 node0 reserve_pages 300 node1
- スクリプトを実行可能にします。
sudo chmod +x /usr/lib/systemd/hugetlb-reserve-pages.sh
/usr/lib/systemd/system/
ディレクトリにhugetlb-gigantic-pages.service
というサービス・ファイルを作成し、次の内容を追加します。[Unit] Description=HugeTLB Gigantic Pages Reservation DefaultDependencies=no Before=dev-hugepages.mount ConditionPathExists=/sys/devices/system/node [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/hugetlb-reserve-pages.sh [Install] WantedBy=sysinit.target
- サービス・ファイルを有効にします。
sudo systemctl enable hugetlb-gigantic-pages
実行時のHugeTLBの構成
場合によっては、実行時にヒュージ・ページに対してリクエストを作成する必要があります。
実行時の特定のNUMAノードのHugeTLBページの構成
次の手順は、実行時にnode2に対してサイズ2048KBの20のHugeTLBページをリクエストする方法を示しています。
- numastatコマンドを実行して、NUMAノードに関連するメモリー統計を表示します。
numastat -cm | egrep 'Node|Huge'| grep -v AnonHugePages
Node 0 Node 1 Node 2 Node 3 Total add HugePages_Total 0 0 0 0 0 HugePages_Free 0 0 0 0 0 HugePages_Surp 0 0 0 0 0
- 指定したサイズの必要なヒュージ・ページ数を、選択したノードに追加します(たとえば、ノード2で2MBサイズの20ページ):
echo 20 | sudo tee /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
numastat
コマンドを再度実行して、リクエストが成功し、リクエストされたメモリー(この例では20 x 2MBページ = 40MB)がHugePages_Total
としてnode2
に追加されていることを確認します:numastat -cm | egrep 'Node|Huge'| grep -v AnonHugePages
Node 0 Node 1 Node 2 Node 3 Total HugePages_Total 0 0 40 0 40 HugePages_Free 0 0 40 0 40 HugePages_Surp 0 0 0 0 0
透過的HugePagesの構成
透過的HugePages (THP)機能は、Oracle Linuxでデフォルトで有効になっています。ただし、システムのニーズに応じて、THPにアクセスして構成することが必要になる場合があります。
次の項では、様々なTHPパラメータとそれらの構成方法の例について説明します。
透過的HugePagesの構成に使用するパラメータ
表6-3 一般的に使用されるTHPパラメータ
パラメータ | ファイルの場所 | 値のオプション |
---|---|---|
enabled |
/sys/kernel/mm/transparent_hugepage/enabled |
THPとそのモードを設定します。このモードは次のいずれかです:
|
defrag |
/sys/kernel/mm/transparent_hugepage/defrag |
THPが使用できない場合にアプリケーションがページをどのように積極的に再利用し、メモリーをデフラグするかを決定します。次のリストに、使用可能なオプションを示します。
|
実行時の透過的HugePagesの構成
次の項では、sysfs
仮想ファイル・システムのTHPパラメータにアクセスして、実行時にTHPを構成する方法の例を示します。
透過的HugePagesの現在のステータスの取得
/sys/kernel/mm/transparent_hugepage/enabled
パラメータを読み取ります。sudo cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
角カッコ内の値は、現在の設定を表します。
透過的HugePagesの現在のステータスの変更
THPの現在のステータスを変更するには、優先する設定を/sys/kernel/mm/transparent_hugepage/enabled
に書き込む必要があります。次の例は、ステータスをalways
に設定する方法を示しています。
- THPの現在のステータスを確認するには、
enabled
パラメータを読み取ります。sudo cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
角カッコ内の値は、現在の設定を表します。
- THPモードを
always
に設定します。echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
enabled
パラメータを読み取って、変更が成功したことを確認します。sudo cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
ノート:
sysfs
などの仮想ファイル・システムは、必ずしもディスク上のファイルとして格納されない項目に、ファイル・システム・インタフェースを提供します。したがって、sysfs
ファイルは、ディスク上の通常の物理ファイルと同じ方法でファイル・コマンドと相互作用することはありません。前述の例では、echo
コマンドを使用した場合、/sys/kernel/mm/transparent_hugepage/enabled
は通常のファイルで使用されるように上書きされませんが、選択したオプションが変更されます:
sudo cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
always
sudo cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
.
透過的HugePagesのデフラグ設定の変更
/sys/kernel/mm/transparent_hugepage/defrag
に書き込む必要がありますノート:
最適なdefrag
設定は、システムごとに異なります。ページおよびメモリー圧縮を再利用すると、使用可能なTHPページ数が増加する可能性があります。ただし、プロセスではCPU時間も使用されます。したがって、特定のシステムの正しいバランスを見つける必要があります。
次の例は、defrag
設定をmadvise
に設定する方法を示しています。
defrag
パラメータの現在の値を確認します。sudo cat /sys/kernel/mm/transparent_hugepage/defrag
[always] defer defer+madvise madvise never
角カッコ内の値は、現在の設定を表します。
/sys/kernel/mm/transparent_hugepage/defrag
パラメータをmadvise
に設定します。echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
defrag
パラメータを読み取って、変更が反映されたことを確認します。sudo cat /sys/kernel/mm/transparent_hugepage/defrag
always defer defer+madvise [madvise] never