如何在 osx 上计算平均负载?它似乎太高了 - 我该如何分析它?

Kri*_*jäl 11 mac cpu-usage macos

一个高级问题:我认为与 linux 系统相比,我的平均负载太高了。我有大约 0.40 1 分钟,基本上没有使用 cpu (0-1%),即使这分布在 4 个内核上,它仍然大约等于 0.10 = 10% 的 cpu 使用,这是不正确的。我现在了解到平均负载不仅考虑 CPU 使用,还考虑到磁盘和网络的 io。因此,我尝试找到 io 等待值,但由于某种原因,这在 mac 上似乎不可用?我当然在 iostat 工具中有 US 和 SY 以及 ID,但没有 io wait % 的迹象(如果我没记错,称为 WI)。

一切都很好,我在我的其他 mac 上有相同的平均负载,我在这里想要了解为什么以这种方式(这么高)计算平均值以及我如何进一步分析它?

我在这个话题上搜索了 2 个小时,但很少或没有人谈论这个,有什么想法吗?

Dan*_*eck 18

负载是可运行进程的平均数量。man 3 getloadavg说:

getloadavg() 函数返回系统运行队列中各个时间段的平均进程数。最多可检索 nelem 样本并将其分配给 loadavg[] 的连续元素。
系统最多施加 3 个样本,分别代表过去 1、5 和 15 分钟的平均值。

您也可以通过运行来获取相同的信息sysctl vm.loadavg


假设 Mac OS X 10.7.2,该getloadavg函数在此处调用此代码(搜索第二次出现的sysctl_loadavg),本质上返回 的当前值averunnable

反过来,这在这里定义:

struct loadavg averunnable =
    { {0, 0, 0}, FSCALE };      /* load average, of runnable procs */
Run Code Online (Sandbox Code Playgroud)

该文件还定义了compute_averunnable,它计算 的新加权值averunnable


调度头文件sched.h中声明为extern,并在所有调度实现xnu-1699.24.8/osfmk/kern/sched_*.c定期通过调用它compute_averagessched_average.c

的参数compute_averunnablesched_nrunin sched_average.c,从sched_run_countin获取它的值sched.h

这个数字由宏sched_run_incr和修改sched_run_decr,专门在文件中使用sched_prim.c,它们是负责线程解除阻塞、分派等的调度原语


所以,回顾一下:

它只是使用可运行线程的数量来计算 5 秒间隔内的负载平均值。


虽然系统完全不同,但我发现很难相信 Linux 的负载总是比 OS X 低。事实上,Linux 似乎只是显示了不同的值

引用维基百科

在现代 UNIX 系统上,线程处理相对于负载平均值的处理各不相同。一些系统为了负载平均计算的目的将线程视为进程:每个等待运行的线程都会将负载加 1。但是,其他系统,尤其是实现所谓的 N:M 线程的系统,使用不同的策略,例如出于加载目的(无论线程数如何),仅对进程进行一次计数,或者仅对用户当前暴露的线程进行计数-thread 调度程序到内核,这可能取决于进程上设置的并发级别。

这篇文章来看,Linux确实使用了可运行的进程数,而不是XNU的线程数。

由于每个可运行进程至少有一个可运行线程,因此 OS X 上的平均负载值将,假设等效的平均负载计算(我没有费心检查),总是至少一样大,因为项目计数他们'重新基于是不同的。

  • 感谢您提供非常详细且正确的答案。这些信息在其他地方很难找到,我相信我之后的其他人也会寻找它。此外,我想表达我的遗憾,因为我不知何故没有收到此线程中的答案通知,而且工作太忙以至于我忘记了它,直到我有时间再次回顾这些事情。答案仍然同样有意义。非常感谢! (2认同)