libhugetlbfsを使ってみる。
最近、比較的大きなデータを大量に処理するプログラムを扱っているのですが、少しでも実行時間を短縮しようと思い、libhugetlbfsを使ってみました。以下は参考にしたページです。
- http://mkosaki.blog46.fc2.com/blog-entry-327.html
- http://blog.goo.ne.jp/u1low_cheap/e/05f7ff0cd7eb54fbb192c4da88af84a7
また、実行環境は以下の通りです。
パッケージはubuntu 8.10 amd64版にはないようだったので、諦めてsourceからmakeします。
私が入れてないだけなのか、ubuntuのamd64版にないのか、単純にmakeすると32bit版をコンパイルしようとして失敗してしまいます。
make
CC32 obj32/elflink.o In file included from /usr/include/features.h:354, from /usr/include/stdio.h:28, from elflink.c:23: /usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory make: *** [obj32/elflink.o] エラー 1
なので、明示的に64bit版を作成するように変数指定してmakeします。
make BUILDTYPE=NATIVEONLY make install PREFIX=$HOME/opt BUILDTYPE=NATIVEONLY
特に問題なくコンパイルできました。
次にhugetlbのOS側設定を行います。
まずはcpuinfoでhugetlbのサイズを確認しておきます。
meminfoを見ると1ページは2MBでした。
(本当は確認するまでもなく、x86系は2Mと決まっているのですが…)
cat /proc/meminfo
…略… HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 65408 kB DirectMap2M: 5961728 kB
今回は4GBをhugetlbとして使いたいので、1500ページ使えるように/etc/rc.localへ追記します。
/bin/echo 1500 > /proc/sys/vm/nr_hugepages mount -t hugetlbfs -o mode=0777 none /mnt/hugetlbfs
リブート後1500ページ取れた事を確認します。
…略… HugePages_Total: 1500 HugePages_Free: 1500 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 202624 kB DirectMap2M: 5824512 kB
プログラムを実行する場合には、いくつかの変数設定を行って使います。
LD_PRELOAD=$HOME/opt/lib64/libhugetlbfs.so HUGETLB_MORECORE=yes ./a.out
mallocだけでなくC++のnewでもhugetlbからメモリを取得するようになるようです。
で、効果のほどはというと、memcpyをやったりするくらいだと特に変化はなく、アーキテクチャを考慮した最適化をしないとやはりダメなのかもしれません。