以下に対して、
革命の日々! ITProのLinuxチューニングの記事がひどい事になっている件についてあまりに酷いのでdisる記事を書こうかと思ったら、末尾に小さく出典:日経Linux 2002年4月号 45ページより (記事は執筆時の情報に基づいており,現在では異なる場合があります)と書いてあった。6年前の記事かよ!!
古い内容が多いので、よい子は信用しないでね。
と物言いがついていて、さらに
ITProのチューニング記事(noatime付加)を検証してみた - 科学と非科学の迷宮また、はてブのコメントを元に relatime オプションを付加して検証を行ったところ、こちらも性能向上は見られませんでした。
となっているのだけど、ちょっと待った!
- 電源投入してからGUIログイン画面が表示されるまでの時間を測定する。
- 「# time find /usr/ -name linux」を実行し、findの実行時間を測定する。
1.はとにかく、2.では検証になりません。
基本的な「atimeはいつ更新されるのか」が誤解されているためです。
atimeは、データを読み出した時に更新される → メタデータを読んでも更新されない
atimeの更新をひと言でまとめると、上の通りになります。
実際にその様子を見てみましょう。
以下のperlスクリプトを動かしてみます。
#!/usr/local/bin/perl use strict; use warnings; my $filename = shift || 'test.txt'; my $line = join '', ( '0' .. '9', 'A' .. 'Z', 'a' .. 'z', '_', "\n" ); sub check_timestamp { my ( $atime, $mtime, $ctime ) = ( stat(shift) )[ 8 .. 10 ]; printf "atime=%d, mtime=%d, ctime=%d\n", $atime, $mtime, $ctime; 1; } { print "# Create\n"; unlink $filename; open my $fh, '>', $filename or die "$filename:$!"; print $fh $line for ( 0 .. 63 ); close $fh; check_timestamp($filename) and sleep(2); } { print "# Just open\n"; open my $fh, '<', $filename or die "$filename:$!"; close $fh; check_timestamp($filename) and sleep(2); } { print "# Open and Read\n"; open my $fh, '<', $filename or die "$filename:$!"; my $cont = do { local $/; <$fh> }; close $fh; check_timestamp($filename); }
こんな感じになります。
# Create atime=1212988860, mtime=1212988860, ctime=1212988860 # Just open atime=1212988860, mtime=1212988860, ctime=1212988860 # Open and Read atime=1212988864, mtime=1212988860, ctime=1212988860
三回目で、やっとatimeが更新されていることに注目してください。atimeはファイルをstat()
しただけは更新せず、open()
してもまだ更新されず、read()
してやっと更新されることがおわかりいただけるかと思います。
よって、
革命の日々! relatimeがどこで実装されているのか調べてみたatimeが更新されるのは、だいたいの4ケースで、writeは最初から入ってない。
- readしたとき
- readdirしたとき
- readlinkしたとき(openの副作用による暗黙のリンクオープンも含む)
- mmapしたとき
ここまでは正しいのですが、
革命の日々! relatimeがどこで実装されているのか調べてみた
- findやメーラーなど、山ほどファイルを開きまくるケース
は前の下りが正しくない。なぜなら、findはメタデータにはアクセスしても、データにはアクセスしないからです。考えてみれば当然で、findの実行そのものがメタデータを改変してしまってはfindの意味がなくなってしまうからです。findのオプションそのものに-atime
があるのに、findがそれを更新してしまっては元も子もなくなってしまいます。
もちろん現代的なfindは、単にファイルを「見つける」だけではなく、-exec
や
-delete
を通してファイルシステムを改変する機能も持っていますが、その基本機能は「メタデータの検索」であって「データの検索/更新」ではありません。
厳密には、findもディレクトリの内容は読むので(ただしreadddir
経由とは限らない; 例えば4.4BSDのfindではfts
という仕組みを使っている)、この時にディレクトリのatimeが更新する可能性がありますが、ファイルのatimeを更新することはありえません。たいていの状況において、ディレクトリ数≪ファイル数なので、find
ではあまり適切なベンチマークが取れないというわけです。
で、noatime
って効用あるの?
私は FreeBSD User なので、Linuxの事情に関して確定的なことは言えませんが、
革命の日々! relatimeがどこで実装されているのか調べてみたこいつがなぜパフォーマンスを落とすかというとatime更新 = inode情報の更新 = ディスク書き込みの必要が発生という連鎖を引き起こすからです。
さらに悪いことに、inode情報はたいていデータ本体とはディスクの物理的な位置が離れているので、無駄なシークが誘発されます。
たいていのディスク系ベンチマークはシーク回数で勝負が決するので、これがベンチで性能がよく見える原因です。
というのはOSやファイルシステムを問わず事実なので、多かれ少なかれ効用が期待できるというのは確かだと思われます。で、4Kbyteのファイルを読み書きした場合を、実際に以下のようにして確認してみました。
- Disk Imageをこさえてmount
- 初期状態(noatime, softupdateあり)で計測
- atimeありで計測
- softupdateもなしで計測
dd if=/dev/zero of=test.ufs2 bs=16M count=64 mdconfig -a -t vnode -f ./test.ufs2 -u 0 newfs -U /dev/md0 mount -o noatime /dev/md0 /mnt mkdir /mnt/dankogai chown dankogai /mnt/dankogai
average: 0.483453, stddev:0.045193 (9.347932%) at bench.pl line 34.
mount -u atime /mnt
average: 0.547789, stddev:0.083034 (15.157962%) at bench.pl line 36.
umount /mnt tunefs -n disable /dev/md0 mount /dev/md0 /mnt
average: 0.543603, stddev:0.096880 (17.821746%) at bench.pl line 34.
#!/usr/local/bin/perl use strict; use warnings; use Time::HiRes qw/time/; my $count = shift || 10000; my $filename = shift || 'test.txt'; my @elapsed = (); for my $i (1..100){ my $started = time(); for my $i (1..$count){ open my $fh, '<', $filename or die "$filename:$!"; my $content = do{ local $/; <$fh> }; close $fh; } my $elapsed = time()-$started; push @elapsed, $elapsed; warn $elapsed; } my ($ave, $stdev) = sub{ my $a = 0; $a += $_ for @_; $a /= @_; my $v = 0; $v += ($_ - $a)**2 for @_; $v /= @_; ($a, sqrt($v)); }->(@elapsed); warn sprintf "average: %f, stddev:%f (%f%%)", $ave, $stdev, ($stdev/$ave)*100;
パフォーマンス向上は、この場合で12%と出ました。扱うファイルはたった一つですし、サイズも4Kbytesで、ファイルシステムには事実上これしかファイルがないという状態ですから、disk cacheはかなり効く、すなわち差が出にくい状況でしたが、有為な差が見られました。これが細かいファイルがもっと沢山あって、それらの内容が頻繁にアクセスされる状況ではもっと出るかと思われます。
というわけで、noatimeというのは比較的損がないおまじないのようであるという結論でした。
Dan the Man with Too Many Kinds of Filesystems to Fiddle
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。