申し訳ないけど、ぬか喜びのような気が。
ディレクトリの中にある大量の小さなファイルを高速に読み込む方法 - 射撃しつつ前転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 total36秒と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";
足跡のこしていきます
応援したいのですが、ランキングバナーがどれをクリックしたらいいのかわからないので、できませんでした><
けど、応援してます。
お互い更新がんばりましょう。