O_DIRECTでopenするときはmemalign使わないとだめだよ
O_DIRECT
でopen
してwrite
したいときがたまにあると思います。
通常のopenしてwriteだとカーネル内部でページキャッシュが使われて、カーネル内部でのメモリコピーが何回か行われちゃいます。が、O_DIRECT
だとページキャッシュをバイパスできて、その結果カーネル内部でのメモリコピー回数が減ります。
通常O_DIRECT
は使わないんですけども、自前でバッファリングとかしてるアプリケーションとかだと(データベースとか)、カーネルのページキャッシュ層と競合してわけわかんないことになったりするのでOFFにしたりします。
あとは、ベンチマークプログラムでファイルシステムの生の性能を知りたいときなどもコレを使います。
んで、僕知らなかったんですがO_DIRECT
でopenしたfdにread/writeするときってalignされたメモリ空間じゃないと受け付けないんですね。つまり、通常のmallocだとだめなんです。これで30分ぐらいハマりました。
普通のmallocで確保したバッファをwrite(2)
に渡そうとすると、perror()
でInvalid argument
エラーが出ちゃいます。
write : Invalid argument
なんでmallocじゃなくてposix_memalign
とか使いましょうって話です。こんな感じ。
if (posix_memalign((void **)&buf, 512, bs)) { perror("posix_memalign"); exit(EXIT_FAILURE); }
ページ空間をまるごと直接アロケーションしちゃってるんですかね?
まあ、manにはちゃんと書いてあります。ちゃんと読めって話ですね。
O_DIRECT The O_DIRECT flag may impose alignment restrictions on the length and address of user-space buffers and the file offset of I/Os.
すべてのコードは以下の通り:
O_DIRECT tipsでした。