通过 iostat 诊断学习中可能的 I/O Bound
16
当 GPU Util 非常低或发生周期性波动,几乎都是因为上游的 Dataloader 没能及时地把数据发送给 GPU。此时,我们需要判断原因是 CPU Bound 还是 I/O Bound。
运行 iostat -x 命令,将返回表头如下的表
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
表头各项的含义
r/s每秒的读操作次数rkB/s每秒从磁盘读取的数据量rrqm/s每秒进行读合并的次数%rrqm读合并操作的百分比r_await读操作的平均等待时间rareq-sz每次读操作的平均大小
w[...]和d[...]同理,分别是写操作和丢弃操作
f/s每秒完成的刷新操作次数f_await刷新请求的平均等待时间aqu-sz总平均请求队列长度%util设备带宽利用率百分比
正常区间
| Metric | HDD | SATA SSD | NVMe SSD |
|---|---|---|---|
r/s/w/s | 80- | 500,000- | 1,000,000- |
r_await/w_await | 20ms- | 1ms- | 0.1ms- |
aqu-sz | 远小于 1 | 小于 1 | 很大也是正常的 |
%util | 70- | 70- | 无意义 |
诊断
典型的 I/O 堵塞:
Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
sda 382.50 9.45 14.50 3.65 38.86 25.31 4.50 0.94 235.50 98.12 47.78 213.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 15.08 93.40
%util = 93.40%磁盘不堪重负aqu-sz = 15.08请求堆积如山r_await = 38.86 ms等待时间极长r/s = 382.50这是一块机械硬盘rareq-sz = 25.31 KB需要读取大量小文件rMB/s = 9.45大部分时间浪费在寻址和建立读写操作上
遵循以上范例分析,能够回答「是否发生 I/O Bound」「I/O Bound 是否因为时间浪费在寻址上」
改善
对于由于读取海量小文件导致 I/O Bound 的情形
- 在内存允许的情形下,总是优先考虑将数据全部预加载进入内存
- 在内存不允许的情形下,总是优先考虑将数据使用 HDF5/TFRecord/... 打包为大文件
- 若以上亦不可行,可以考虑重排读取样本的顺序以增强空间 locality;若有效,你将观察到
%rrqm的上升;可以考虑禁止同时执行多个任务以减小寻址负担