# 第 37 章实验:顺序读 vs 随机读 ## 做什么 `seqrand.c` 先在当前目录写一个测试文件(默认 128MB,最多 256MB),然后用 `O_DIRECT` 打开它(绕过页缓存,让每次 `pread` 真的到达设备),分别测: 1. **顺序读,1MB 一次**:大请求 + 连续位置——磁盘最擅长的模式; 2. **顺序读,4KB 一次**:位置连续,但每个请求很小; 3. **随机读,4KB 一次**:原书的"随机负载"(random workload)。 测完自动删除测试文件。 ## 怎么跑 ``` make ./seqrand # 默认 128MB 文件、4000 次随机读 ./seqrand 256 8000 # 256MB 文件、8000 次随机读 make clean ``` ## 该观察到什么 - 顺序 1MB 的带宽远高于随机 4KB,差距通常是几十到上百倍。 - 在真正的机械硬盘(HDD)上,随机 4KB 每次要付出"寻道 + 旋转"约 5~15ms,吞吐只有 0.3~1MB/s 左右(原书 Figure 37.6:Cheetah 0.66MB/s、Barracuda 0.31MB/s),与顺序读相差 200~300 倍。 - 在 WSL2 上,Linux 看到的"磁盘"其实是 Windows 主机上的一个虚拟磁盘文件(VHDX),底下多半是 SSD,还隔着主机的缓存。SSD 没有磁头,也就没有寻道和旋转延迟,所以**随机 4KB 和顺序 4KB 差距不大**;两者都远慢于 1MB 大请求,是因为每个请求都有固定开销(系统调用、虚拟化层、设备命令处理)。这说明原书的 TIP 在 SSD 上依然成立:**尽量用大块、顺序地传输数据**。 ## 为什么要 O_DIRECT 不加 `O_DIRECT` 的话,刚写完的文件还在页缓存里,读出来的其实是内存,测不到设备。`O_DIRECT` 要求缓冲区地址、偏移、长度都按块(这里 4096 字节)对齐,所以用 `posix_memalign` 分配缓冲区。若文件系统不支持 `O_DIRECT`(例如 tmpfs),程序会报错退出——请在 ext4 等普通磁盘文件系统上运行。