什么是“写”function适当的缓冲区大小?

我正在使用低级I / O函数'write'在我的代码(Linux上的C语言)中将一些数据写入磁盘。 首先,我将数据积累在内存缓冲区中,然后在缓冲区满时使用“写入”将数据写入磁盘。 那么“写”最好的缓冲区大小是多less? 根据我的testing,速度越快越好,所以我在这里寻找答案。

Solutions Collecting From Web of "什么是“写”function适当的缓冲区大小?"

在做文件系统块大小倍数的写操作中,可能有一些优势,特别是如果你正在更新文件。 如果您写入的文件少于部分块,则操作系统必须读取旧块,并合并新的内容,然后将其写出。 如果您按顺序快速写入小块,这不一定会发生,因为更新将在稍后刷新的内存缓冲区中完成。 尽管如此,如果你没有在每个写入操作中填充一个块(和一个正确对齐的块:在块大小的倍数的偏移量处的块大小的倍数),偶尔会触发一些低效率。

这个传输大小的问题不一定会消失与mmap。 如果你映射一个文件,然后将一些数据存入地图,那么你正在把页面弄脏。 那个页面稍后要刷新:这是不确定的。 如果你使另一个接触同一页面的memcpy ,那么这个页面现在可能是干净的,而你又把它弄脏了。 所以它被写了两次。 页面大小的页面对齐副本将是要走的路。

你会希望它是CPU页面大小的倍数,以便尽可能高效地使用内存。

但理想情况下,你想要使用mmap,所以你永远不必自己处理缓冲区。

您可以使用<stdio.h>定义的BUFSIZ

否则,请使用页面大小sysconf(_SC_PAGESIZE)的小数倍(例如,该值的两倍)。 大多数Linux系统有4千字节的页面(通常与文件系统块大小相同或小一些)。

正如其他答复,使用mmap(2)系统调用可以帮助。 GNU系统(例如Linux)有一个扩展: fopen的第二个模式字符串可能包含后面的m ,当发生这种情况时,GNU libc会尝试mmap

如果处理的数据几乎与内存(或其中的一半)相同,则可能还需要使用madvise(2)来微调mmap性能。

另请参阅这个答案 ,与您的问题非常相似。 (你可以使用64K字节作为一个合理的缓冲区大小)。

“最佳”大小取决于底层文件系统。

statfstat调用填充数据结构struct stat ,其中包含以下字段:

 blksize_t st_blksize; /* blocksize for file system I/O */ 

操作系统负责为write()块填充这个字段。 但是,调用write()与“完全对齐”的内存也是很重要的(例如, malloc调用的结果)。 最简单的方法是使用提供的<stdio.h>流接口(使用FILE *对象)。

正如在这里的其他答案一样,使用mmap在很多情况下也可以非常快速。 请注意,它不适合某些类型的流(例如套接字和管道)。

这取决于RAM,VM等的数量以及正在写入的数据量。 更一般的答案是基准什么缓冲区最适合您正在处理的负载,并使用最好的工作。