プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

relatimeがどこで実装されているのか調べてみた このエントリーをはてなブックマークに追加

ITProのLinuxチューニングの記事がひどい事になっている件について
http://mkosaki.blog46.fc2.com/blog-entry-535.html


という数本前の記事について、id:shiumachiさんが追試してくれました。

つ http://d.hatena.ne.jp/shiumachi/20080605


むむむ、すばらしいです。
特にrelatimeのあたりが秀逸です。relatimeの性能測定って他にあんまりないのではないかしら。

複数の方からご指摘いただいておりますが、noatimeはあの記事のなかで数少ない、現在でも意味のあるオプションです。
せっかくなので、お礼がてら、relatimeについてちょいと追記してみます。

まず、atimeまわりのオプションの意味から


デフォルト:   常にatimeを更新する
noatime:    常にatimeを更新しない
nodiratime: 対象がファイルのときは常に更新、ディレクトリの時は常に更新しない
relatime:    inode上でatimeがmtimeやctimeよりも古くなってしまった時だけ更新


nodiratimeとrelatimeは両方ともnoatimeの副作用を軽減するために追加された機能です。
この副作用を説明するにあたって、atimeとは何か、について説明します。

まず、atimeとは(Access TIME)の略でその名のとおり、アクセスした時間を表します。
うーん、説明になってない。
こいつがなぜパフォーマンスを落とすかというと
atime更新 = inode情報の更新 = ディスク書き込みの必要が発生
という連鎖を引き起こすからです。
さらに悪いことに、inode情報はたいていデータ本体とはディスクの物理的な位置が離れているので、無駄なシークが誘発されます。
たいていのディスク系ベンチマークはシーク回数で勝負が決するので、これがベンチで性能がよく見える原因です。

あと、ITproの記事に


一方,書き出し性能はほとんど変化していない。これはnoatimeオプションを指定していても,ファイルの書き出し時にはatimeが更新されるためである。


という記述もあるけど、これは間違い。

atimeが更新されるのは、だいたい
1.readしたとき
2.readdirしたとき
3.readlinkしたとき(openの副作用による暗黙のリンクオープンも含む)
4.mmapしたとき
の4ケースで、writeは最初から入ってない。


で、話を戻すとnoatimeが非常に効くのは以下の2つのケース。

1.findやメーラーなど、山ほどファイルを開きまくるケース
2.ベンチマークソフトなど、あんまり大きくないバッファをひたすらreadしまくるケース

で、atimeなんてstat(2)あたりでアプリが明示的にチェックしない限り意味ないんだから、
特定アプリしか使わないマウントポイントに関しては、atimeを記録しなくても大丈夫なはずだよねー
というアイデアが出てくる。と。

で、nodiratimeとrelatime は両方ともnoatimeの副作用を緩和するために開発されたもので

relatimeは、いくつかのアプリケーションは特定のファイルの更新をファイルしていて、
mtimeとatimeを比較してmtimeのほうが新しければ、「誰かが俺が読んだ後に更新した」
とみなしてもう一度読みにいくわけ。
だから、mtimeが新しいときはatimeの更新に意味があるけど、mtimeが古いときは
それ以上atimeを更新しても誰もうれしくねーぜ。
という、なんというかmuttをinotifyに対応させろよ。とか頭がよぎるような
ステキwork around 実装。

nodiratimeは、ファイルのatimeをチェックするアプリケーションはよくあるが(メーラとか)
ディレクトリのatimeをチェックするアプリケーションなんてないんじゃね?
という思想でディレクトリだけ記録を省いてみた。
というやっぱり決めうち感あふれるwork around.

となっています。
たぶん、relatimeで99%の人がハッピーになれるので、ビジネスでlinuxを使っている人は、
ディストリにバックポートを依頼するとハッピーになれるかもしれません。
#特にしかたなくnoatimeを使っている人にとっては。

んで、ここからが詳細。

まとめ記事としてはいつものように、kerneltrapが秀逸

http://kerneltrap.org/node/14148

パッチ自体は以下、超短くて分かりやすい

http://lkml.org/lkml/2006/8/25/381


最近のカーネルだとリファクタリングされた結果、上記パッチ投稿時と関数のつくりが若干変わってるので、関数全体ものせとく


/**
* touch_atime - update the access time
* @mnt: mount the inode is accessed on
* @dentry: dentry accessed
*
* Update the accessed time on an inode and mark it for writeback.
* This function automatically handles read only file systems and media,
* as well as the "noatime" flag and inode specific "noatime" markers.
*/
void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
struct timespec now;

if (mnt && mnt_want_write(mnt))
return;
if (inode->i_flags & S_NOATIME)
goto out;
if (IS_NOATIME(inode))
goto out;
if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
goto out;

/*
* We may have a NULL vfsmount when coming from NFSD
*/
if (mnt) {
if (mnt->mnt_flags & MNT_NOATIME)
goto out;
if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
goto out;
if (mnt->mnt_flags & MNT_RELATIME) {
/*
* With relative atime, only update atime if the
* previous atime is earlier than either the ctime or
* mtime.
*/
if (timespec_compare(&inode->i_mtime,
&inode->i_atime) < 0 &&
timespec_compare(&inode->i_ctime,
&inode->i_atime) < 0)
goto out;
}
}

now = current_fs_time(inode->i_sb);
if (timespec_equal(&inode->i_atime, &now))
goto out;

inode->i_atime = now;
mark_inode_dirty_sync(inode);
out:
if (mnt)
mnt_drop_write(mnt);
}
EXPORT_SYMBOL(touch_atime);


見てのとおり、超単純で、atimeが更新されるようなケースで、mtime, ctimeよりも新しかったら無視。
というだけ。
てゆーか、あんまり速度が落ちる可能性があるコードに見えないなー

さらに個人的なレス



回数 real user sys
1 80.533 1.031 2.370
2 0.741 0.345 0.396
3 0.719 0.325 0.394

このように、同一起動時に複数回コマンドを実行すると、2回目以降の実行時間は極端に短くなります。

これはおそらくキャッシュを読み込んでるためだと思われますが、詳しい動作はわかりません。

(知ってる人がいたら教えてほしい)



このテスト手順では、ようするにfindを使って、readdirしまくるってテストなので、
一回目はdcacheとicacheが空なので、全部ディスク上から読まないといけない。
だけど、二回目以降はメモリ操作ですむからだと思う。


YOU FAIL 相対的な大小が重要です! ランキング!

関連記事


linux | 【2008-06-09(Mon) 02:21:43】 | Trackback:(2) | Comments:(2)
コメント
問題の記事の筆者です。自分でも比較的マシと思ってた部分にもこんな重大なミスがあるとは…
write時のatimeについては今に至るまで完全に誤解してました
きちんとコードを見て理解しないとダメですね。反省です
2008-06-08 日 23:07:40 | URL | 末安泰三 #- [ 編集]

管理人です。どもども
404 Blog Not Foundさんが非常に興味深い記事をトラックバックしてくれているので、合わせて読むのがオススメです。
勉強になります。
2008-06-09 月 04:55:30 | URL | kosaki #- [ 編集]
コメントの投稿(メールアドレスは公開されますのでMail欄は使わないことをオススメします)

以下に対して、 Linuxチューニング 第1部第1回 ファイル・アクセスを高速化:ITpro 革命の日々! ITProのLinuxチューニングの記事がひどい事になっている件について あまりに酷いのでdisる記事を書こうかと思ったら、末尾に小さく 出典:日経Linux 2002年4月
【2008-06-09 Mon 15:47:30】 | 404 Blog Not Found
404 Blog Not Found さんがトラックバックくれてるみたいだ。 すばらしいまとめ記事をありがとうございます。 せっかくなのでお礼がてら、トラバ...
【2008-06-09 Mon 18:47:51】 | 革命の日々!
  1. 無料アクセス解析