我一直在研究iowait
顶部实用程序输出中显示的属性,如下所示。
top - 07:30:58 up 3:37, 1 user, load average: 0.00, 0.01, 0.05
Tasks: 86 total, 1 running, 85 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
iowait
一般定义如下:
“这是 CPU 空闲并且有一些 IO 待处理的时间。”
我的理解是进程是在单个CPU上运行的。当它因为用完其时隙或被阻塞而被取消调度后,它最终可以在任何一个 CPU 上再次被调度。
在 IO 请求的情况下,将进程置于不间断睡眠状态的 CPU 负责跟踪时间iowait
。其他 CPU 报告的空闲时间与它们实际空闲的时间相同。这个假设正确吗?
此外,假设有一个很长的 IO 请求(意味着该进程有几次机会被调度,但由于 IO 未完成而没有被调度),CPU 如何知道存在“待处理 IO”?此类信息是从哪里获取的? CPU 如何简单地发现某个进程已进入睡眠状态一段时间以等待 IO 完成,因为任何 CPU 都可能使该进程进入睡眠状态。这个“pending IO”的状态是如何确认的呢?
答案1
CPU 不知道这些,任务调度程序知道。
你引用的定义有些误导;目前的procfs(5)
联机帮助页有一个更准确的定义,但有一些注意事项:
iowait
(自 Linux 2.5.41 起)(5) 等待I/O完成的时间。该值并不可靠,原因如下:
CPU不会等待I/O完成;
iowait
是任务等待 I/O 完成的时间。当CPU因未完成的任务I/O而进入空闲状态时,将在该CPU上调度另一个任务。在多核CPU上,等待I/O完成的任务并不在任何CPU上运行,因此
iowait
每个CPU的值很难计算。在某些情况下,该字段的值可能会减少。
iowait
一般来说,尝试测量等待 I/O 所花费的时间。没有被追踪经过一个特定的CPU,也不可能是(上面的第2点——这也符合你想知道的)。被测量每CPU,但尽可能。
任务调度程序“知道”有挂起的 I/O,因为它知道它因等待 I/O 而挂起了给定的任务。这是根据in_iowait
领域中的每个任务进行跟踪的task_struct
;你可以in_iowait
在调度器核心查看它是如何设置、跟踪和清除的。Brendan Gregg 最近关于 Linux 平均负载的文章包括有用的背景信息。每当考虑到计时器滴答时,并且 CPU“上”的当前进程处于空闲状态时,iowait
中的条目(/proc/stat
最终是中的条目)就会递增;top
你可以通过account_idle_time
在调度程序的CPU时间跟踪代码。
因此,更准确的定义是“当没有更好的事情可做时,CPU 花费在等待 I/O 上的时间”...