可能重复:
How do you determine the ideal buffer size when using FileInputStream?
使用C ++的istream
系列read()
或C fread()
从文件(或任何输入流)读取原始数据时,必须提供一个缓冲区,并且要读多少数据。我见过的大多数程序似乎都在512到4096之间任意选择2的幂。
修改
大多数答案似乎是在编译时无法确定。我很高兴在运行时找到它。
答案 0 :(得分:19)
来源:
How do you determine the ideal buffer size when using FileInputStream?
最佳缓冲区大小与许多内容有关:文件系统 块大小,CPU缓存大小和缓存延迟。
大多数文件系统都配置为使用4096或8192的块大小。 理论上,如果您配置缓冲区大小,那么您正在阅读一些 字节多于磁盘块,与文件系统的操作 效率极低(即如果你将缓冲区配置为 每次读取4100个字节,每次读取需要2个块读取 文件系统)。如果块已经在缓存中,那么你就结束了 支付RAM的价格 - > L3 / L2缓存延迟。如果你运气不好而且 块还没有在缓存中,你支付的价格 disk-> RAM延迟。
这就是为什么你看到大多数缓冲区大小为2的幂,一般来说 大于(或等于)磁盘块大小。这意味着其中之一 您的流读取可能会导致多个磁盘块读取 - 但是 那些读取将始终使用完整的块 - 没有浪费的读取。
确保这通常还会导致其他性能友好的参数影响读取和后续处理:数据总线宽度对齐,DMA对齐,内存缓存行对齐,整数虚拟内存页。
答案 1 :(得分:4)
答案 2 :(得分:1)
一个可能的原因是磁盘扇区的大小通常为512字节,因此,假设所有硬件层和缓存都会导致低级代码实际上能够有效地使用此事实,那么读取其中的倍数会更有效。除非您正在编写设备驱动程序或进行无缓冲读取,否则它可能无法使用。
答案 3 :(得分:0)
我没有理由知道它必须是两个人的力量。您受限于缓冲区大小必须在最大size_t
范围内,但这不太可能是一个问题。
显然,缓冲区越大越好但这显然不可扩展,因此必须在编译时或最好在运行时考虑系统资源注意事项。
答案 4 :(得分:0)
1。它是否有/应该是2的幂的原因,或者这只是程序员对2的幂的自然倾向?
不是真的。它可能应该是甚至在数据总线宽度的大小来简化内存复制,所以任何分成16的东西都适合当前的技术。使用2的幂可能使其适用于任何未来的技术。
2。什么是“理想”数字? “理想”我的意思是它会是最快的。
最快的就是尽可能多。但是,一旦超过几千字节,与使用的内存量相比,性能差异非常小。
我认为它必须是它的倍数 底层设备的缓冲区大小?或者可能是底层流 对象的缓冲区?我如何确定这些缓冲区的大小 是吗,无论如何?
你无法真正了解底层缓冲区的大小,或者取决于它们保持不变。
一旦我这样做,就会使用它的倍数给出任何速度 只是使用确切的大小增加?
有些,但很少。
答案 5 :(得分:0)
我认为缓冲区的理想大小是硬盘驱动器中一个块的大小,因此它可以在存储或从硬盘驱动器中获取数据时与缓冲区正确映射。