2007-01-26

ディレクトリの深さと open|close のパフォーマンスの違いに因果関係があるの かどうかの調査

どこかから coss の調査してみてはどうよ、といわれたのでちまちま調べることにしてみました。 HTTPなどのキャッシュサーバとして用いられている squid に、coss (Cyclic Object storage system) というキャッシュの記憶機構がついており、これのパフォーマンスが良いのって本当かよとか yamazさんのところで語られている のですが、この文章のなかにこんなやり取りが


xxxxx : 3年ぐらい前、apacheをプロファイリングしたら、select()の次にopen()がコストを食ってました。で、そのときは、open("/home/xxxx/hoge/hoge/hoge.gif") とかしたとき、/home, /home/xxxx,...のディレクトリファイルを読みに行って、そこでDISK IOが詰まってるんじゃないか?と思ってました。
yamaz : なかなか説得力あるなw

これのなかの、そもそもディレクトリ階層的に深いところにあるとパフォーマンス落ちるのかどうかを調べてました。 対象のシステムは FedoraCore6 (Linux kernel 2.6.18-1.2798.fc6) というものです。


まずは、こんなPerlスクリプトでディレクトリを適当に掘ってみました。


#!/usr/bin/perl

use Digest::MD5;
# set dirname entries
my @dirnames;
my $depth = 10;
my $num_in_dir = 3;
for (my $i = 0; $i < $num_in_dir; $i ++) { push(@dirnames, $i); }

mkdir ("./nest");
make_nest_dir("./nest", $depth);

sub make_nest_dir ($$) {
my $curdir = shift;
my $curnestnum = shift;
$curnestnum -= 1;
if ($curnestnum) {
foreach my $each (@dirnames) {
my $dir_mk = "$curdir/$each";
if (!mkdir($dir_mk)) {
print STDERR "Can't make directory($dir_mk) : $!n";
next;
}
make_nest_dir($dir_mk, $curnestnum);
}
}
system("touch $curdir/file");
print "make : $curdirn"
}

そすると、こんな感じのディレクトリが nest/ 内にできます


0/file
0/0/file
0/0/0/file
....
0/0/0/0/0/0/0/0/0/file
0/0/0/0/0/0/0/0/1/file
.....

この状態で shell の glob の wildcard を使って任意の数のディレクトリとか取ればよい状態にします。 たとえば 0/?/?/?/?/file0/0/0/0/0/?/?/?/?/file でのファイルの open/close をジャンジャンやらせた時の時間の比較をすると。 ちなみにこんなコード使って、open|close の繰り返しをしてみました。


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>

void usage (){
printf("openclose_test [count] [files....]n count: number of open/close for one filen");
}
int main (int argc, char** argv) {
int loopc = 0, fd, i, j;
if (argc < 3) {
usage();
exit(1);
}
loopc = atoi(argv[1]);
if (loopc < 1) {
usage();
exit(1);
}
for (i = 0; i < loopc; i++) {
for (j = 2; j < argc; j++) {
fd = open(argv[j], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Failed to open %s : %sn",
argv[j], strerror(errno));
continue;
}
close(fd);
}
}
}

で、これで、nest/?/?/?/?/file を 16384回 open/close した場合は8.381秒ぐらいで、nest/0/0/0/0/0/?/?/?/?/file を 16384回 open/close した場合は11秒ぐらいでした。 ディレクトリの深さによってパフォーマンスに変化あることは確かなようです。

0 件のコメント:

コメントを投稿