理想的缓冲区大小是多少? [复制]

Posted

技术标签:

【中文标题】理想的缓冲区大小是多少? [复制]【英文标题】:What would be an ideal buffer size? [duplicate] 【发布时间】:2012-05-28 17:25:37 【问题描述】:

可能重复:How do you determine the ideal buffer size when using FileInputStream?

当使用 C++ 的 istream 系列的 read() 或 C 的 fread() 从文件(或任何输入流)读取原始数据时,必须提供缓冲区,以及要读取的数据量。我见过的大多数程序似乎都是在 512 和 4096 之间任意选择 2 的幂。

    是否有理由必须/应该是 2 的幂,或者这只是程序员对 2 的幂的自然倾向? 什么是“理想”数字? “理想”是指它是最快的。我认为它必须是底层设备缓冲区大小的倍数?或者可能是底层流对象的缓冲区?无论如何,我将如何确定这些缓冲区的大小?一旦我这样做了,使用它的倍数是否会比仅使用精确大小来提高速度?

编辑 大多数答案似乎是在编译时无法确定。我可以在运行时找到它。

【问题讨论】:

我相信缓冲区大小取决于编译器或机器(抱歉,我不知道是哪一个,或者两者兼而有之)。唯一知道的方法是尝试读取各种大小的数据。它应该很快,所以做 100 次并取平均值。它不应该是一条直线。我的猜测是,当您越过必须读取另一个数据缓冲区的点时,您应该注意到。 (或者,您可以挖掘 C/C++ 的源代码...) 如有疑问,请始终将缓冲区大小设为 2 的幂。其他程序员会认为你这样做是出于某种聪明的原因。 ;-) 重新编辑:运行时间没有多大帮助。您需要在开发时进行分析,除非您每次启动自适应缓冲代码时都可以承受大量数据的极端“热身运行”。 【参考方案1】:

来源:How do you determine the ideal buffer size when using FileInputStream?

最佳缓冲区大小与许多事情有关:文件系统 块大小、CPU 缓存大小和缓存延迟。

大多数文件系统配置为使用 4096 或 8192 的块大小。 理论上,如果您配置缓冲区大小,那么您正在阅读一些 比磁盘块多字节,对文件系统的操作 可能效率极低(即,如果您将缓冲区配置为 一次读取 4100 个字节,每次读取需要 2 个块读取 文件系统)。如果块已经在缓存中,那么你结束了 付出 RAM -> L3/L2 缓存延迟的代价。如果你不走运并且 块还没有在缓存中,你付出了代价 磁盘->RAM 延迟也是如此。

这就是为什么您会看到大多数缓冲区大小为 2 的幂,并且通常 大于(或等于)磁盘块大小。这意味着其中之一 您的流读取可能会导致多个磁盘块读取 - 但是 这些读取将始终使用完整块 - 不会浪费读取。

确保这一点通常还会导致影响读取和后续处理的其他性能友好参数:数据总线宽度对齐、DMA 对齐、内存高速缓存行对齐、虚拟内存页面的整数。

【讨论】:

【参考方案2】:
    至少在我的情况下,假设底层系统正在使用大小也是 2 的幂的缓冲区,因此最好尝试匹配。我认为现在的缓冲区应该比“大多数”程序员倾向于制作的缓冲区大一点。例如,我会选择 32 KB 而不是 4 KB。 不幸的是,很难提前知道。例如,这取决于您的应用程序是 I/O 还是 CPU 密集型。

【讨论】:

我不需要提前。我可以在运行时找到它【参考方案3】:
    我认为大多数情况下它只是选择一个“整数”。如果计算机以十进制工作,我们可能会选择 1000 或 10000 而不是 1024 或 8192。没有很好的理由。

一个可能的原因是磁盘扇区的大小通常为 512 字节,因此读取其中的倍数会更有效,假设所有硬件层和缓存导致低级代码实际上能够有效地使用这一事实。除非您正在编写设备驱动程序或进行无缓冲读取,否则它可能无法做到。

【讨论】:

【参考方案4】:

我没有理由知道它必须是 2 的幂。您受到缓冲区大小的限制,必须在最大 size_t 范围内,但这不太可能成为问题。

显然缓冲区越大越好,但这显然不可扩展,因此必须在编译时或最好在运行时考虑系统资源。

【讨论】:

【参考方案5】:

1 .是否有理由必须/应该是 2 的幂,或者这只是程序员对 2 的幂的自然倾向?

不是真的。它可能应该是数据总线宽度的大小以简化内存复制,因此任何划分为 16 的东西都适合当前的技术。使用 2 的幂使其很可能适用于任何未来的技术。

2 。 “理想”的数字是多少? “理想”是指它会是最快的。

尽可能快。但是,一旦超过几千字节,与您使用的内存量相比,性能差异将非常小。

我认为它必须是 底层设备的缓冲区大小?或者可能是底层流 对象的缓冲区?我将如何确定这些缓冲区的大小 是吗?

您无法真正知道底层缓冲区的大小,或者依赖于它们保持不变。

一旦我这样做了,使用它的倍数会给出任何速度 比仅使用确切大小增加?

一些,但很少。

【讨论】:

【参考方案6】:

我认为理想的缓冲区大小是硬盘中一个块的大小,因此它可以在存储或从硬盘获取数据时与缓冲区正确映射。

【讨论】:

以上是关于理想的缓冲区大小是多少? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

BufferedReader 中的缓冲区大小是多少?

每 10 毫秒录制一次音频的音频缓冲区大小和 FFT 大小是多少?

串口通信缓冲区大小上限是多少?默认是512字节。

InternetReadFile 的共同平均缓冲区大小是多少?

Linux管道缓冲区有多少数据? linux管道缓冲区大小可以配置吗?

更改缓冲区大小以在 C 中复制文件