C 盘 I/O - 在文件的相同偏移量处先读后写会使读取吞吐量非常低
C Disk I/O - write after read at the same offset of a file will make read throughput very low
背景:
我正在开发一个与数据库相关的程序,我需要按顺序将脏元数据从内存刷新到磁盘。
/dev/sda1 是卷格式,所以 /dev/sda1 上的数据将逐块访问,如果顺序访问,这些块在物理上是相邻的。
而我直接使用I/O,所以I/O会绕过文件系统的缓存机制,直接访问磁盘上的块。
问题:
打开/dev/sda1后,我将读取一个块,更新块并将块写回到从[=50=开始的相同偏移量],迭代。
代码如下 -
//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,读取吞吐量将是21MB/s,写入吞吐量是169MB/s.
如果我在pwrite之后做pread,写吞吐量是115MB/s,读吞吐量是208MB/s.
我也尝试了read()/write()和aio_read()/aio_write(),但问题依旧。不知道为什么同一个文件位置读后写会导致读吞吐量这么低
如果一次访问更多块,像这样
pread(file, buffer, num_blocks * block_size, i*block_size);
问题会缓解,请参阅chart。
And I use direct I/O, so the I/O will bypass the caching mechanism of the file system and access directly the blocks on the disk.
如果您的设备上没有文件系统并直接使用设备read/write,则没有文件系统缓存。
您观察到的行为是典型的磁盘访问和 IO 行为。
I found that if I don't do pwrite, read throughput is 125 MB/s
原因:磁盘只读数据,不用回offset写数据,少了1次操作。
If I do pwrite, read throughput will be 21 MB/s, and write throughput is 169 MB/s.
原因:您的磁盘可能具有更好的写入速度,可能磁盘缓冲区正在缓存写入而不是直接写入介质。
If I do pread after pwrite, write throughput is 115 MB/s, and read throughput is 208 MB/s.
原因:很可能写入的数据被缓存在磁盘级别,因此读取从缓存而不是媒体获取数据。
要获得最佳性能,您应该使用异步 IOs 和一次块数。但是,您必须使用合理数量的块,不能使用非常大的数量。应该通过反复试验找出最佳方法。
背景:
我正在开发一个与数据库相关的程序,我需要按顺序将脏元数据从内存刷新到磁盘。 /dev/sda1 是卷格式,所以 /dev/sda1 上的数据将逐块访问,如果顺序访问,这些块在物理上是相邻的。 而我直接使用I/O,所以I/O会绕过文件系统的缓存机制,直接访问磁盘上的块。
问题:
打开/dev/sda1后,我将读取一个块,更新块并将块写回到从[=50=开始的相同偏移量],迭代。
代码如下 -
//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,读取吞吐量将是21MB/s,写入吞吐量是169MB/s.
如果我在pwrite之后做pread,写吞吐量是115MB/s,读吞吐量是208MB/s.
我也尝试了read()/write()和aio_read()/aio_write(),但问题依旧。不知道为什么同一个文件位置读后写会导致读吞吐量这么低
如果一次访问更多块,像这样
pread(file, buffer, num_blocks * block_size, i*block_size);
问题会缓解,请参阅chart。
And I use direct I/O, so the I/O will bypass the caching mechanism of the file system and access directly the blocks on the disk.
如果您的设备上没有文件系统并直接使用设备read/write,则没有文件系统缓存。
您观察到的行为是典型的磁盘访问和 IO 行为。
I found that if I don't do pwrite, read throughput is 125 MB/s
原因:磁盘只读数据,不用回offset写数据,少了1次操作。
If I do pwrite, read throughput will be 21 MB/s, and write throughput is 169 MB/s.
原因:您的磁盘可能具有更好的写入速度,可能磁盘缓冲区正在缓存写入而不是直接写入介质。
If I do pread after pwrite, write throughput is 115 MB/s, and read throughput is 208 MB/s.
原因:很可能写入的数据被缓存在磁盘级别,因此读取从缓存而不是媒体获取数据。
要获得最佳性能,您应该使用异步 IOs 和一次块数。但是,您必须使用合理数量的块,不能使用非常大的数量。应该通过反复试验找出最佳方法。