LoginSignup
1
2

More than 5 years have passed since last update.

ext4のnoauto_da_allocのベンチマーク

Last updated at Posted at 2017-02-23

はじめに

先の記事(ext4のnoauto_da_allocオプションの詳細)noauto_da_allocオプションがどう効くかをコードベースで確認したが、これが実際にどれくらいパフォーマンスに響くのかを簡易にテストしてみた。

テスト環境は、Ubuntu 14.04(Linux-3.13くらい)、i7-4790Kくらい、HDDはよくあるSATA接続のもの、RAMはたくさんめです。

テストスクリプト

ddtest1.sh
#!/bin/sh

dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
dd if=/dev/zero of=test.dat bs=64k count=1024
ddtest2.sh
#!/bin/sh

dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat
dd if=/dev/zero of=test.dat bs=64k count=1024
rm test.dat

テスト結果

noauto_da_allocなしの時(デフォルト)

[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m6.020s
user    0m0.000s
sys     0m0.447s
[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m5.888s
user    0m0.000s
sys     0m0.376
[rarul@tina ~]$ time ./ddtest_pc2.sh 2&>1 > /dev/null
real    0m0.384s
user    0m0.005s
sys     0m0.379s
[rarul@tina ~]$ time ./ddtest_pc2.sh 2&>1 > /dev/null
real    0m0.319s
user    0m0.007s
sys     0m0.312s

noauto_da_allocありの時(オプション変更)

noauto_da_allocでremountする。

# mount -o remount,noauto_da_alloc / /

でテストを開始、

# mount -o remount,noauto_da_alloc / /
[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m0.385s
user    0m0.005s
sys     0m0.379s
[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m0.305s
user    0m0.004s
sys     0m0.301

ついでにnodelallocもテストする

fstabでnodelallocを足して再起動してテスト、時間置いてからの一発目がなぜか遅いという症状が出るものの、おおむね想定通りの速度。

[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m1.199s
user    0m0.000s
sys     0m0.441s
[rarul@tina ~]$ time ./ddtest_pc1.sh 2&>1 > /dev/null
real    0m0.436s
user    0m0.000s
sys     0m0.436s
[rarul@tina ~]$ time ./ddtest_pc2.sh 2&>1 > /dev/null
real    0m0.473s
user    0m0.004s
sys     0m0.442s
[rarul@tina ~]$ time ./ddtest_pc2.sh 2&>1 > /dev/null
real    0m0.443s
user    0m0.003s
sys     0m0.440s

ただ、remountではなぜかnodelallocがうまく効いていないようなベンチマーク結果だった。/proc/mounts的にはnodelallocになってたんだけどなぁ。ext4のコードを再確認して見るもそれらしきは見あたらずに原因はよくわからない。vopsまで含めてinodeがキャッシュされていたということにしておこう...

# mount -t ext4 -o remount,nodelalloc / /

テスト結果の解説

ext4はデフォルトでは、
- renameで上書きが発生するタイミング
- truncateでサイズ0にした場合のcloseのタイミング
の2つの場合に、filemap_flush()を呼ぶことでIOをスタートさせようとする。通常はバッファキャッシュでIOが遅延され、場合によってはIOがスタートする目に消された結果何もしないのが、filemap_flush()が呼ばれることで必ずIOがこのタイミングでスタートしてしまう。noauto_da_allocをつけるとこの挙動を行わなくなるのでこの特定ケースでパフォーマンスが向上する。

前者はともかく、後者はユーザランドレベルではもっと具体的に下記の場合になるかと思う。

  • ファイルが存在する場合にopen(2)O_TRUNCで呼ぶ
  • truncate(2)でファイルサイズをゼロにする

「ファイルを消して作り直すくらいならO_TRUNCでファイルサイズをゼロにしてしまう」なんていうのはプログラムによってはやってそうな処理ではある。SQLitejournal_mode=truncate使っているとか。

終わりに

先にソースコードを読んだ上での恣意的なテストだったというわけで、なんという出来レース...

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2