HugePageとは
HugePageは特定の用途用にロックダウンしたメモリ範囲を用意する。HugePageの名の通り、通常4KBのページサイズが2MB、1GBに増えるため処理するページ数が少なくなりCPUの負荷を抑えることができる。仮想マシンを動作させるなど大量のメモリーを使用する場合。HugePageを利用することでパフォーマンスの低下を抑えられる。
実施環境
物理マシン
- ProxmoxVE 7.0-11
- CPU AMD Ryzen 5 1600 12コア
- RAM 16GB
ゲストマシン
- Windows 10 Home
- CPU 10コア
- RAM 8GB
- PCI-Passthrough等の設定済み(今回の話とは直接関係ないです)
初期状態の確認
CPUの確認。「pse」もしくは「pdpe1gb」の文字列が含まれていればHugePage対応CPU。「pse」であれば2MB、「pdpe1gb」であれば1GBサイズのページが作成できる。
cat /proc/cpuinfo | egrep -o pse | head -n 1
# pse
cat /proc/cpuinfo | egrep -o pdpe1gb | head -n 1
# pdpe1gb
使用しているRyzen 1600は両方とも対応していた。
メモリの確認
cat /proc/meminfo | grep -i huge
AnonHugePages: 8271872 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
「Hugepagesize:2048 kB」の箇所に注目。現在のHugePageのページあたりの容量の設定は2MBということがわかる。1GBの設定の場合は下記のようになる。
root@kiyoura:~# cat /proc/meminfo | grep -i huge
略
Hugepagesize: 1048576 kB
GRUBの設定変更
8GBのページをゲスト専用に用意するケースを考える。
2MB設定の場合
「/etc/default/grub」を編集する。
「hugepagesz=1G default_hugepagesz=2M hugepages=4096 transparent_hugepage=never"」を後ろに書き足す。「2M」の部分が先程確認した数値。仮想マシンで使用しているメモリの容量が8GB。8192MB/2MBでページ数は4096必要。
GRUB_CMDLINE_LINUX_DEFAULT="quiet 〜略〜 hugepagesz=1G default_hugepagesz=2M hugepages=4096 transparent_hugepage=never"
1GB設定の場合
8GB/1GBで8ページ必要
GRUB_CMDLINE_LINUX_DEFAULT="quiet 〜略〜 hugepagesz=1G default_hugepagesz=1G hugepages=8 transparent_hugepage=never"
default_hugepageszの部分でmeminfoで表示されるページサイズ設定が変更される。
編集後はgrubを更新し再起動。
update-grub
起動後にHugePageの状態を確認。4096ページと表示されるはず。
cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 4096
HugePages_Free: 4096
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 8388608 kB
仮想マシンの設定
仮想マシンのCPU設定で、「NUMAを有効化」をチェック。「pdpe1gb」フラグをOnにする。
仮想マシンの設定ファイルを編集する。パスは「/etc/pve/qemu-server/(仮想マシン番号).conf」
「hugepages: 2」の行を追記。場所はどこでもいい。1ページ1GBの場合は1024と記入。
hotplug: 0
hugepages: 2
ide0: none,media=cdrom
ゲスト起動後
「HugePages_Free」が0になっていることが確認できる。
cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 4096
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 4096
Hugepagesize: 2048 kB
Hugetlb: 8388608 kB
サマリで、ゲストのメモリ利用状況を確認するとほぼ0になっている。
仮想マシンを完全にシャットダウンした場合、利用されたHugePageは開放されてしまうようで、再度ゲストの起動を試みた際にHugePageがなくAllocation Errorとなってしまう。Windowsの再起動ではHugePageは維持され問題なかった。
cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
ゲストシャットダウン後に再度HugePage作成
以下のコマンドで再度HugePageを用意できる。
echo 4096 > /proc/sys/vm/nr_hugepages
実行後
cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 4096
HugePages_Free: 4096
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 8388608 kB
作成後は再度ゲストを起動することができた。
ちなみに1GBの設定の場合、
echo 8 > /proc/sys/vm/nr_hugepages
起動前のHugePage作成自動化
いちいち上記のコマンドを実行するのは面倒なため、自動化する。ProxmoxVEにはhookscript機能があり、ゲストマシンの起動・シャットダウンのタイミングで任意のperlスクリプトを実行させることができる。
「スニペット」をlocalで有効化する。これで「/var/lib/vz/snippets/」ディレクトリが作成される。
hookscriptのサンプルが「/usr/share/pve-docs/examples/guest-example-hookscript.pl」にあるため、これをコピーする。
cp /usr/share/pve-docs/examples/guest-example-hookscript.pl /var/lib/vz/snippets/make_4096_hugepage.pl
「/var/lib/vz/snippets/make_4096_hugepage.pl」を編集する。
起動直前のタイミング「pre-start」の場合に「echo 4096 > /proc/sys/vm/nr_hugepages」コマンドが打たれるようにする。
if ($phase eq 'pre-start') {
# First phase 'pre-start' will be executed before the guest
# ist started. Exiting with a code != 0 will abort the start
print "$vmid is starting, doing preparations.\n";
# ここから
my $command = "echo 4096 > /proc/sys/vm/nr_hugepages";
system($command);
# ここまで
# print "preparations failed, aborting."
# exit(1);
ゲストマシンの設定「/etc/pve/qemu-server/(仮想マシン番号).conf」に以下を追記
hookscript: local:snippets/make_4096_hugepage.pl
これで起動とシャットダウンを繰り返しても正常に動作するようになる。
WindowsでのHugePageの利用
メモリーの測定にSandraというベンチマークソフトが良さそうなので、使用してみたところHugePageが使用できていないことがわかった。
「特権の不足により、大きなメモリーページを使用できません」
グループポリシーの設定変更が必要なことがわかった。Windows10のHome版ではgpeditが使用できないため、下記の記事を参考にgpeditを使用できるようにした。
そして下記手順を参考にポリシーを変更した。ページロック可能対象ユーザーとして「Everyone」を指定した。
再起動後、警告は消えたためHugePageが使用できるようになったと思われる。