syncとfsync
理解が曖昧だったので、きちんと調べてみた。
sync(2)
sync() を呼び出すと、バッファされたファイルのメタデータとデータ本体に対して行われた全ての変更が、対応するファイルシステムに書き込まれる。
fsync(2)
fsync() は、ファイル記述子 fd で参照されるファイルの、メモリ内で存在する修正されたデータ (つまり修正されたバッファキャッシュページ) を、ディスクデバイス(またはその他の永続ストレージデバイス) に転送 (「フラッシュ」) し、これにより、システムがクラッシュしたり、再起動された後も、変更された全ての情報が取り出せるようになる。「フラッシュ」には、ライトスルー (write through) や (存在する場合には) ディスクキャッシュのフラッシュも含まれる。この呼び出しは 転送が終わったとデバイスが報告するまでブロックする。
さらに調べてみると、カーネルスレッドのpdflushがバッファからディスクに書き込みをする、らしい。 これだけでは面白くないのでwriteのたびにfsyncして、同期的にファイル書き込みしたときの速度差を測ってみる。
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char** argv) { int fd; char buff[1024]; int i; sprintf(buff, "test%d\r\n", getpid()); fd = open("/tmp/kotaro", (O_WRONLY | O_CREAT)); for (i = 0; i < 10000; i++) { write(fd, buff, strlen(buff)); if ( argc > 1 ) { fsync(fd); } } close(fd); }
fsyncなし
$ time ./write_fsync real 0m0.026s user 0m0.004s sys 0m0.018s
fsyncあり
$ time ./write_fsync --with-fsync real 0m2.771s user 0m0.017s sys 0m0.336s
1ループあたり0.27msもfsyncありのほうが遅いという結果に。
さらに素晴らしい記事を発見。勉強になるなぁ。 http://d.hatena.ne.jp/naoya/20070523/1179938637