背景:C盤I/O - 寫出同一文件的偏移後將使讀取吞吐量很低
我正在開發一個數據庫相關的程序,我需要刷新髒的元數據內存到磁盤順序。 /dev/sda1是卷的格式,因此/ dev/sda1上的數據將被逐塊訪問,並且如果按順序訪問,則塊之間是物理上相鄰的。 而且我使用直接I/O,所以I/O將繞過文件系統的緩存機制並直接訪問磁盤上的塊。
問題:
開放的/ dev/sda1的之後,我會讀一個塊,更新塊和寫回該塊相同的從/ 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後做PREAD,寫吞吐量115 MB/s的,和讀取吞吐量是208 MB/s的。 ()/ write()和aio_read()/ aio_write(),但問題依然存在。我不知道爲什麼在一個文件的相同位置讀取後寫入會使讀取吞吐量如此之低。
如果同時接入多塊,這樣
pread(file, buffer, num_blocks * block_size, i*block_size);
的問題會緩解,請參閱chart。
你的塊大小是多少?您很可能會看到硬件緩存和預讀對您正在訪問的磁盤的影響。 'pwrite()'填充緩存,如果下一個'pread()'用於不同的數據,則不會緩存它。在'pwrite()'之後執行'pread()'操作可以直接從磁盤的硬件緩存中讀取數據。 –
我不知道物理塊的大小,我在程序中設置爲256KB。感謝您的評論,現在我認爲這很可能是由磁盤緩衝區引起的。 – Leo