7

バックグラウンド:

データベース関連のプログラムを開発しており、ダーティ メタデータをメモリからディスクに順次フラッシュする必要があります。/dev/sda1 はボリューム形式なので、/dev/sda1 上のデータはブロックごとにアクセスされ、シーケンシャルにアクセスするとブロックは物理的に隣接します。また、ダイレクト I/O を使用しているため、I/O はファイル システムのキャッシュ メカニズムをバイパスし、ディスク上のブロックに直接アクセスします。

問題:

/dev/sda1 を開いた後、1 つのブロックを読み取り、ブロックを更新して、ブロックを /dev/sda1 の先頭からの同じオフセットに繰り返し書き込みます。

コードは以下のようなものです -

//block_size = 256KB
int file = open("/dev/sda1", O_RDWR|O_LARGEFILE|O_DIRECT);
for(int i=0; i<N; i++) {
    pread(file, buffer, block_size, i*block_size);
    // Update the buffer
    pwrite(file, buffer, block_size, i*block_size);
}

pwrite を実行しない場合、読み取りスループットは125 MB/sであることがわかりました。

pwrite を実行すると、読み取りスループットは21 MB/sになり、書き込みスループットは169 MB/sになります。

pwrite の後に read を行うと、書き込みスループットは115 MB/sで、読み取りスループットは208 MB/sです。

read()/write() と aio_read()/aio_write() も試しましたが、問題は残ります。ファイルの同じ位置で読み取り後に書き込みを行うと、読み取りスループットが非常に低くなる理由がわかりません。

このように、一度により多くのブロックにアクセスする場合

pread(file, buffer, num_blocks * block_size, i*block_size);

問題は軽減されます。チャートを参照してください。

4

1 に答える 1