🎰

HugePages の効果

2022/08/23に公開

HugePages を使うことによる利点

  1. TLB ヒット率の向上による主に CPU 負荷の軽減。-> マルチ環境による TPS の向上。
  2. メインメモリ上にあるページテーブルのサイズ削減によるメモリ使用量の削減。
  3. (副次的) HugePages として確保されたメモリ帯は、スワップしない。

なお、ページテーブルはプロセスごとに保持されるのでHugePagesの使用有無に関わらずプロセスが増えるほどメモリはそのページテーブル分使う。

Linux 上で HugePages を使っているプロセス一覧調べるスクリプト

perl -lane '/KernelPageSize/ and $F[1]!=4 and print qq/$ARGV\t$_/' /proc/*/smaps > /tmp/hugepages_tmp

while read -r rec;do
	pid=`echo $rec | awk -F'/' '{print $3}'`
	process=`ps -p $pid -f -o pid,cmd | tail -1`
	echo "$rec => $process"
done < /tmp/hugepages_tmp

/proc/*/smapsより以下のアドレスを使っているメモリについては HugePagesを使用していると判断できる

HugePages を使っているプロセスのsmapsには以下の記載がある

7fc72a600000-7fc736000000 rw-s 00000000 00:0d 35114      => メモリアドレス                /anon_hugepage (deleted)
Size:             190464 kB
KernelPageSize:     2048 kB => OS カーネルから見た論理ページサイズ
MMUPageSize:        2048 kB => MMUでの物理ページサイズ
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
FilePmdMapped:         0 kB
Shared_Hugetlb:    45056 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
THPeligible:    0
ProtectionKey:         0
VmFlags: rd wr sh mr mw me ms de ht sd

検証

PostgreSQL で HugePages を on/off して検証する。

  • ベンチマーク用のツールである pgbench を用いる。
  • スケールファクター(-s) 1 あたりおおよそ 16M 程度のデータベースサイズ。
  • pgbench -i -s 500 で初期化。
  • shared_buffers = 10GB
  • AWS EC2 r5.xlarge (4vCPU/RAM 16GB)上の PostgreSQL 13.7 で検証

huge_pages = off

この場合ページサイズは 4kb と見なされる。

### ベンチマーク
$ pgbench -c 30 -j 4 -T 10
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 500
query mode: simple
number of clients: 30
number of threads: 4
duration: 10 s
number of transactions actually processed: 58052
latency average = 5.198 ms
tps = 5771.742572 (including connections establishing)
tps = 5773.500733 (excluding connections establishing)

### 実行中のページテーブルサイズ
$ cat /proc/meminfo  | grep PageTables
PageTables:        69428 kB

huge_pages = on

この場合ページサイズは 2MB と見なされる。


# sysctl -w vm.nr_hugepages=10000
vm.nr_hugepages = 10000

# cat /proc/meminfo  | grep -i Huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:   10000
HugePages_Free:    10000
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:        20480000 kB

### ベンチマーク
$ pgbench -c 30 -j 4 -T 10
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 500
query mode: simple
number of clients: 30
number of threads: 4
duration: 10 s
number of transactions actually processed: 63244
latency average = 4.749 ms
tps = 6316.863968 (including connections establishing)
tps = 6318.607556 (excluding connections establishing)

### 実行中のページテーブルサイズ
$ cat /proc/meminfo  | grep PageTables
PageTables:         8836 kB

考察

検証結果より、HugePages を利用していた方が、TPS が高く(なお、この際両者のCPU使用率は同程度でしたので要するにTBLキャッシュにヒットする分CPUの使用効率が高いのではないかと考えられる)、かつ、ページテーブルに使用するメモリ量も圧倒的に少ないことが分りました。特に大規模なワークロードになるほど、HugePages を有効にする性能的メリットは高いのではないでしょうか。

Referrence:
https://www.percona.com/blog/2018/12/20/benchmark-postgresql-with-linux-hugepages/
https://linuxjf.osdn.jp/JFdocs/The-Linux-Kernel-4.html

Discussion