繁体   English   中英

最佳文件输出缓冲区大小是多少?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM