ファイルシステム上のファイルにキャッシュを解さずread/writeするためには、DirectIOで操作する必要がある。DirectIOを操作するには、
- ファイルをオープンする時に、O_DIRECTオプションを付与する
- read/writeで操作する際のバッファは、512KB(Linux kernel2.6以降)でアライメントする(したがって、バッファ意はposix_memalignで確保する。mallocや配列で確保するとread()/write()時に、EINVALエラーとなる)
- コンパイル時に"_GNU_SOURCE"オプションを付与する。
サンプルコードは以下の通り。
#include <unistd.h> #include <fcntl.h> #define BLOCKSIZE 512 int main(void) { int fdi, fdo; int size = 100 * 1024 * 1024; /* 100MB */ char *buf; /* allocate buffer memory */ posix_memalign( (void **)&buf, BLOCKSIZE, size); /* open file */ fdi = open("file_in", O_RDONLY |O_DIRECT ); fdo = open("file_out",O_WRONLY|O_CREAT|O_TRUNC|O_DIRECT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP ); /* copy "fdi" file to "fdo" file. */ read(fdi, buf, size); write(fdo,buf, size); }
コンパイルコマンド
$ gcc -D_GNU_SOURCE -o directio directio.c
テスト
$ dd if=/dev/zero of=file_in bs=1024 count=102400 102400+0 records in 102400+0 records out 104857600 bytes (105 MB) copied, 1.31783 s, 79.6 MB/s $ ./directio
straceコマンドでシステムとレースしてみても
$ strace ./directio <中略> open("file_in", O_RDONLY|O_DIRECT) = 3 open("file_out", O_WRONLY|O_CREAT|O_TRUNC|O_DIRECT, 0660) = 4 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 104857600) = 104857600 write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 104857600) = 104857600 exit_group(104857600) = ? $