问题回顾
-
fwrite
默认缓冲区大小(buf
):4096 字节(4KB)。 - 写入数据长度:64MB(64 × 1024 × 1024 = 67,108,864 字节)。
- 问题:实际 I/O 次数是多少?
关键概念
-
fwrite
的缓冲机制:fwrite
是标准库(stdio
)提供的函数,默认使用用户空间缓冲区(buf
)。- 数据先写入缓冲区,缓冲区满后才会触发
write
系统调用,执行实际磁盘 I/O。 - 缓冲区的目的是减少 I/O 次数(批处理写入)。
-
write
系统调用:- 每次
write
调用对应一次实际的磁盘 I/O(假设无操作系统或磁盘缓存干扰)。
- 每次
- 计算逻辑:
- 实际 I/O 次数 = 数据总量 / 缓冲区大小(向上取整)。
- 如果数据量是缓冲区大小的整数倍,则无需额外 I/O。
计算过程
- 数据总量:
64 \text{MB} = 64 \times 1024 \times 1024 = 67,108,864 \text{ 字节}
- 缓冲区大小:
4096 \text{ 字节}
- 实际 I/O 次数:
\text{I/O 次数} = \left\lceil \frac{67,108,864}{4096} \right\rceil = 16,384
- 因为
67,108,864 \div 4096 = 16,384
是整数,所以无需额外 I/O。
- 因为
验证
- 总数据量:
4096 \times 16,384 = 67,108,864 \text{ 字节} = 64 \text{MB}
- 结论:
- 每次
fwrite
填满 4096 字节缓冲区后触发一次write
。 - 64MB 数据恰好需要 16,384 次
write
调用(即 16,384 次实际 I/O)。
- 每次
特殊情况讨论
- 如果数据量不是缓冲区大小的整数倍(例如 64MB + 1 字节):
- 最后一次
write
会写入剩余的部分数据(1 字节)。 - 此时 I/O 次数为 16,384 + 1 = 16,385 次。
- 最后一次
- 操作系统/磁盘缓存的影响:
- 现代操作系统会缓存磁盘 I/O(
page cache
),可能合并多次write
调用。 - 但从
fwrite
的角度,write
调用次数仍为 16,384 次(实际磁盘 I/O 可能更少)。
- 现代操作系统会缓存磁盘 I/O(
最终答案
实际 I/O 次数 = 16,384 次。