如何计算CPU使用率?


74

在我的桌面上,我有一个小部件,可以告诉我当前的CPU使用率。它还显示了我两个内核中每个内核的用法。

我一直想知道,CPU如何计算正在使用多少处理能力?此外,如果CPU挂断了一些密集的计算,那么它(或处理此活动的任何对象)如何检查使用情况而又不挂断?


1
您是否在询问CPU电源管理,例如CPU检测它是否消耗大量电能并产生大量热量?例如,Skylake的芯片上有一个微控制器来进行电源管理(与CPU内核分开),并带有来自温度/功率传感器的输入以及一些工作量信息。(例如,在运行具有大量缓存/ TLB未命中的代码时,即使在操作系统中,它甚至使用100%CPU时,它甚至会降频)...
Peter Cordes

2
...这回答了第2部分,与第1部分(操作系统级别的平均负载)无关。请参阅为什么此延迟循环在几次迭代后没有睡眠后开始运行得更快?链接。您是在问CPU如何检查自己的使用情况,而不是操作系统跟踪CPU的使用情况。也许这不是您的意思,但这是对该问题的解释的答案:P
彼得·科德斯

Answers:


31

The CPU doesn't do the usage calculations by itself. It may have hardware features to make that task easier, but it's mostly the job of the operating system. So obviously the details of implementations will vary (especially in the case of multicore systems).

总体思路是查看CPU需要完成的工作队列有多长时间。操作系统可能会定期查看调度程序,以确定其必须执行的操作数量。

这是Linux中的一个功能(从Wikipedia摘录),用于执行上述计算

#define FSHIFT   11  /* nr of bits of precision */
#define FIXED_1  (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1  1884  /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5  2014  /* 1/exp(5sec/5min) */
#define EXP_15 2037  /* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
    load *= exp; \
    load += n*(FIXED_1-exp); \
    load >>= FSHIFT;

unsigned long avenrun[3];

static inline void calc_load(unsigned long ticks)
{
    unsigned long active_tasks; /* fixed-point */
    static int count = LOAD_FREQ;

    count -= ticks;
    if (count < 0) {
        count += LOAD_FREQ;
        active_tasks = count_active_tasks();
        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
    }
}

至于问题的第二部分,大多数现代操作系统是多任务的。这意味着OS不会让程序占用所有处理时间,而不会自己占用任何处理时间(除非您让它这样做)。换句话说,即使应用程序似乎挂起,操作系统可以占用一些时间来完成自己的工作。


3
“ CPU本身实际上不执行任何CPU使用率计算。” -采样处理器上的工作负载的OS代码在哪里执行?:)
阿妮2010年

2
@Ani:恩,没有代码,CPU本身无法做任何事情,不是吗?:-)我的意思是,没有任何操作码或机器指令可以告诉您CPU使用情况,即AFAIK。
在silico 2010年

@aaa鲤鱼:啊,这很有趣,我已经纠正了。尽管我很确定OS仍然必须基于性能计数器来计算(总体)CPU使用率。
在silico 2010年

当然,您仍然必须处理它们,它们只是寄存器中的数字。性能计数器给予相当不错的信息操作系统可能无法,例如高速缓存未命中,等等
Anycorn

2
@Vatine:我将OP的问题解释为与CPU负载有关,因为该问题涉及性能。如果CPU A有2个待处理任务,而CPU B有20个待处理任务(两者都执行相似的事情),则两者可能都占用了100%的CPU时间,但是CPU A的性能更好。
在silico 2010年

70

当没有其他任务可以运行时,有一个特殊的任务称为空闲任务。使用百分比只是我们不运行空闲任务的时间的百分比。操作系统将保持运行空闲任务所花费的总时间:

  • 当我们切换到空闲任务时,将t设置为当前时间
  • 当我们离开空闲任务时,将(当前时间-t)添加到运行总计

如果我们将运行总时间间隔为n秒的两个样本分开,我们可以将运行空闲任务所花费的n秒的百分比计算为(第二个样本-第一个样本)/ n

请注意,这是操作系统执行的操作,而不是CPU。任务的概念在CPU级别不存在!(实际上,空闲任务将使处理器通过HLT指令进入睡眠状态,因此CPU会知道何时不使用处理器)。

关于第二个问题,现代操作系统具有抢先性的多任务功能,这意味着操作系统可以随时退出您的任务。操作系统实际上是如何从任务中窃取CPU的?中断:http : //en.wikipedia.org/wiki/Interrupt


12
++极好的答案。我还发现自己告诉人们程序正在运行或正在等待,并且分别使用了100%或0%的内核。他们看到的“利用率百分比”只是一个很短的运行平均值。您会认为这很明显,但有时并非如此。
Mike Dunlavey 2010年

1
+1简要说明了所有内容,谢谢!很高兴知道,实际上,CPU可以通过使用HLT指令和中断来“不执行任何操作”。
tjklemz

@tjklemz:有趣的事实:现代x86使用特殊的args monitor/mwait指令进入睡眠状态。 hlt节省了一些功率,但仅节省了最浅的睡眠状态(C1)。相关阅读:software.intel.com/en-us/blogs/2008/03/27/... / software.intel.com/en-us/blogs/2008/04/29/...。请注意,Skylake最终让OS完全控制硬件,至少在活动时进行频率缩放,但OS仍可以决定睡眠状态。
彼得·科德斯

16

要获取CPU使用率,请定期采样处理时间,并找出差异。

例如,如果这些是进程1的CPU时间:

kernel: 1:00:00.0000
user:   9:00:00.0000

然后两秒钟后再次获得它们,它们是:

kernel: 1:00:00.0300
user:   9:00:00.6100

您减去内核时间(相差0.03)和用户时间(0.61),将它们加在一起(0.64),然后除以2秒的采样时间(0.32)。

因此,在过去的两秒钟内,该进程平均使用了32%的CPU时间。

每个平台上获取此信息所需的特定系统调用(显然)是不同的。在Windows上,如果需要快捷方式可以使用GetProcessTimesGetSystemTimes。用或空闲CPU时间。


8

一种方法如下:

选择一个采样间隔,例如每5分钟(300秒)实际经过的时间。你可以从这里得到gettimeofday

获取您在那300秒内使用的处理时间。您可以使用该times()呼叫获取此信息。这将是new_process_time - old_process_time,其中old_process_time是您从上一个时间间隔保存的处理时间。

然后,(process_time/elapsed_time)*100.0 您的cpu百分比就是您可以设置一个警报,使其每300秒发出一次信号来进行这些计算。

我有一个过程,我不想使用超过特定目标cpu百分比的过程。这种方法效果很好,并且与我的系统监视器非常吻合。如果我们使用过多的cpu,我们会睡一会儿。


2

这是我基本了解类似代码后的基本理解。诸如任务管理器之类的程序或诸如NtQuerySystemInformation()之类的窗口小部件访问系统调用,并使用从OS收集的信息来简单计算CPU空闲或被使用的时间百分比(以标准时间)。CPU知道何时空闲,因此可以确定何时不空闲。这些程序确实可能被阻塞...我的笨拙笔记本电脑的任务管理器在计算CPU使用率时一直冻结,直到达到100%。

可以在MSDN网站上找到很多很酷的示例代码,其中显示了用于计算一组指令的CPU使用率的函数调用:http : //msdn.microsoft.com/zh-cn/library/aa364157( VS.85) .aspx

这些系统调用的作用是访问内核代码,我相信...这超出了我的理解范围。



1

好吧,据我了解,有一个巨大的

while(true){}

操作系统旋转的循环。您可以从该循环中管理过程。它允许外部代码在块中直接在处理器上执行。在不夸张的前提下,这是对实际情况的简化。


0
  1. CPU不会“挂起”,它只是在峰值容量下运行,这意味着它每秒处理的指令数量与其物理能力一样。其中一些指令是计算CPU使用率的过程。如果应用程序尝试执行的操作速度超过CPU的能力,那么它们只会被延迟,从而“挂断”。

  2. CPU利用率的计算基于总可用利用率。因此,如果一个CPU有两个内核,一个内核使用率是30%,另一个是60%,则总体利用率是45%。您还可以查看每个单独核心的用法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.