2009年07月28日 15:00 [Edit]

この記事をクリップ! newsing it! Buzzurlにブックマーク b.hatena.ne.jp/entry それって単なるdisk cacheの差では?

申し訳ないけど、ぬか喜びのような気が。

ディレクトリの中にある大量の小さなファイルを高速に読み込む方法 - 射撃しつつ前転
dirdumpを実行すると、以下のような結果が得られた。
./dirdump data  0.26s user 6.43s system 18% cpu 36.962 total
./dirdump data --nosort 0.40s user 9.28s system 1% cpu 14:08.45 total
 36秒と850秒という、圧倒的な速度差(23.6倍!)が得られた。

このdirdump、FreeBSDでもそのまま動いたのだけど、4096bytes/file * 65556 files で動かしてみた結果が、こう。ファイルの生成に使ったscriptはentryの最後に。

% /usr/bin/time -l ./a.out data
        1.23 real         0.09 user         1.14 sys
      2220  maximum resident set size
         4  average shared memory size
       732  average unshared data size
       128  average unshared stack size
       467  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
         1  voluntary context switches
       115  involuntary context switches
% /usr/bin/time -l ./a.out data --nosort
        1.24 real         0.12 user         1.11 sys
      2220  maximum resident set size
         4  average shared memory size
       732  average unshared data size
       128  average unshared stack size
       467  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
         1  voluntary context switches
       139  involuntary context switches

こんなことをしてさえ、これしかかからない。

/usr/bin/time -l /bin/sh -c 'find data -type f | xargs cat | wc'
 6140990 268435456
        4.25 real         3.91 user         1.96 sys
     13344  maximum resident set size
         9  average shared memory size
       241  average unshared data size
       126  average unshared stack size
      6264  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
      4386  voluntary context switches
      1091  involuntary context switches

ファイルシステムは、FreeBSD標準のUFS2、ディスクはこう。

ATA channel 1:
    Master:  ad2  SATA revision 1.x

確かOSも違えばFSも違えばHDDも違う、違うづくしではあるけれど、いくらなんでもこれは差がつき過ぎではないか。

で、思い当たるのは、ディスクキャッシュのサイズ。FreeBSDの例では、全てがDisk Cacheに乗っているように見受けられる。実際iostatで観察してみても、ディスクアクセスはほとんど発生していなかった。確かに当該マシンのメモリーは2GB。ファイルの内容込みで4KB * 65,536 = 256MBなら余裕でキャッシュできる。

で、実際に 先代 MacBook Pro 2.5GHz/4GB RAM、Hitachi HTS542525K9SA00 上で VMWare 2.05, Ubuntu 9.04, ext3/relatime (仮想ディスク、事前領域割当なし), 512MB RAM な仮想Linuxホストで試してみたのが、以下である。

% time ./a.out data

real	0m12.141s
user	0m0.024s
sys	0m10.205s
% time ./a.out data --nosort

real	0m8.284s
user	0m0.044s
sys	0m7.516s
% time ./a.out data

real	0m7.075s
user	0m0.048s
sys	0m6.888s
% time ./a.out data --nosort

real	0m7.041s
user	0m0.032s
sys	0m6.768s

見てのとおり、最初の実行時を除き、有為さは見られない。最初の実行のみやや遅いのは、ディスクキャッシュがまだ埋まっていないからだと推察できる。

というわけで私の結論。

  • 元発言は、Disk Cacheにだまされている
  • ユーザーランド上のディスク利用最適化は、OSの前では幻のようなもの
  • UTF2 on FreeBSDはこういうケースで高速
  • 下手にあがくよりRAMを積み増せ
  • (未検証だが経験則的に)ユーザーランドであがくなら、FSではなくDBMにデータを押し込む手の方がよさげ

Dan the Man with Too Many Filesystems to Fiddle

#!/usr/local/bin/perl
use strict;
use warnings;
srand;
my ($dir, $count) = @ARGV;
die "$0 dir count" unless $dir and $count;
open my $rfh, '<', "/dev/urandom" or die "/dev/urandom:$!";

for (1..$count){
    my $fn = sprintf("%04x%04x", rand(0x10000), rand(0x10000));
    my $path = "$dir/$fn";
    -f $path and next;
    open my $wfh, '>', $path or die "$path:$!";
    read $rfh, my $content, 4096;
    print $wfh $content;
    printf "%d:$path\r", $_;
}
print "\n";

Posted by dankogai at 15:00 │Comments(4)TrackBack(0)

この記事へのトラックバックURL

この記事へのソーシャルブックマーク
はてなブックマーク
Livedoorクリップ
0 Buzzurl
この記事へのコメント
--nocacheなんてオプションがどこから出てきたのか
Posted by 通りすがり at 2009年07月28日 16:18
テスト用に作ったファイルがディスク上で綺麗に整列しちゃってたりしないですよね?
それなら差は出なくなるはず。
テスト用のファイルの作成方法にかなり大きな影響を受けるはずなので、そこをどうしたかも公開した方が良いように思います。
Posted by tagomoris at 2009年07月28日 16:21
エントリありがとうございます。
ディスクキャッシュは測定の度に http://d.hatena.ne.jp/tkng/20090717/1247813731 にメモした方法でクリアしています。HDDの方のキャッシュはフラッシュできていませんが、実験データサイズと比較して無視できる範囲だと考えています。
Posted by tkng at 2009年07月28日 17:02
通りすがりさん他、
細かいtypoを直しました。
Dan the Typo Generator
Posted by at 2009年07月28日 18:15