[英]What is the optimal file output buffer size?
例如,请参见下面的代码。 size
为1MB,运行速度肯定快于1MB。我认为这是因为IO系统调用次数减少了。 这是否意味着我将永远受益于更大的缓冲区大小? 我希望如此并进行了一些测试,但似乎存在一些限制。 size
为2时,运行速度将比为1时快得多,但是并没有那么快。
有人可以更好地解释吗? 最佳缓冲区大小可能是多少? 我为什么不从无限扩大其规模中受益匪浅。
顺便说一句,在本示例中,为简单起见,我写到了stdout
,但是我也在考虑何时写入磁盘中的文件。
enum
{
size = 1 << 20
};
void fill_buffer(char (*)[size]);
int main(void)
{
long n = 100000000;
for (;;)
{
char buf[size];
fill_buffer(&buf);
if (n <= size)
{
if (fwrite(buf, 1, n, stdout) != n)
{
goto error;
}
break;
}
if (fwrite(buf, 1, size, stdout) != size)
{
goto error;
}
n -= size;
}
return EXIT_SUCCESS;
error:
fprintf(stderr, "fwrite failed\n");
return EXIT_FAILURE;
}
通常,您不需要最佳的缓冲区大小,这可能需要在OS中查询系统参数,并进行复杂的估计甚至对目标环境进行基准测试,并且它是动态的。 幸运的是,您只需要一个足够好的值。
我会说4K〜16K缓冲区适合大多数正常使用。 其中4K是普通计算机(x86,arm)支持的页面大小的幻数,也是通常物理磁盘扇区大小(512B或4K)的倍数。
如果您要处理大量数据(千兆字节),您可能会意识到简单的fwrite-model不足以阻止其阻塞。
在大型分区上,群集大小通常为32 KB。 在较大的读/写请求中,如果系统看到有一系列连续的群集,它将把它们组合成一个I / O。 否则,它将请求拆分为多个I / O。 我不知道最大I / O大小是多少。 在某些旧的SCSI控制器上,它为64 KB或1 MB-8 KB(控制器中为17或255个描述符)。 对于IDE / Sata,我已经能够完成2 MB的IOCTL,确认它是带有外部总线监视器的单个I / O,但是我从未测试过确定极限。
对于使用k> 2的自底向上合并排序的外部排序,使用10> 100 MB的读/写大小可减少随机访问开销。 该请求将被分解为多个I / O,但读或写将是顺序的(在理想情况下)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.