如何计算CPU使用率?

时间:2010-09-20 01:07:03

标签: algorithm performance cpu cpu-usage cpu-architecture

在我的桌面上,我有一个小小部件告诉我当前的CPU使用情况。它还显示了我的两个核心的使用情况。

我一直想知道,CPU如何计算其处理能力的使用量?此外,如果CPU挂起进行一些强烈的计算,它怎么能(或处理这个活动的任何东西)检查使用情况,而不会挂断?

8 个答案:

答案 0 :(得分:61)

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

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

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

请注意,这是操作系统所做的事情,而不是CPU。 CPU级别不存在任务的概念! (实际上,空闲任务会使处理器使用HLT指令进入休眠状态,因此CPU确实知道它何时没有被使用)

至于第二个问题,现代操作系统是先发制人的多任务,这意味着操作系统可以随时切换远离您的任务。操作系统如何实际窃取CPU远离您的任务?中断:http://en.wikipedia.org/wiki/Interrupt

答案 1 :(得分:28)

CPU本身不进行使用计算。它可能具有硬件功能,使该任务更容易,但它主要是操作系统的工作。显然,实现的细节会有所不同(特别是在多核系统的情况下)。

一般的想法是看看CPU需要做多长时间的事情。操作系统可以定期查看调度程序以确定它必须执行的操作的数量。

This is a function Linux in (ripped from Wikipedia) that performs said calculation

#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);
    }
}

至于问题的第二部分,大多数现代操作系统都是multi-tasked。这意味着操作系统不会让程序占用所有处理时间而不会自己拥有(unless you make it do that)。换句话说,即使应用程序出现挂起,操作系统也仍然为自己的工作偷走一些时间。

答案 2 :(得分:13)

要获得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上,如果您需要使用 total 的快捷方式或空闲CPU时间,则可以使用GetProcessTimesGetSystemTimes

答案 3 :(得分:7)

一种方法如下:

选择采样间隔,例如每5分钟(300秒)实际经过的时间。您可以从gettimeofday获取此信息。

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

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

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

答案 4 :(得分:2)

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

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

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

答案 5 :(得分:1)

有很多方法可以做到:

处理器维护多个测量性能的计数器,您可以使用Papi接口访问它们。例如,这里有一个简短的介绍:http://blogs.oracle.com/jonh/entry/performance_counter_generic_events

还:http://www.drdobbs.com/tools/184406109

你可能想要的计数器是PAPI_TOT_CYC,它是繁忙周期的数量(如果我没记错的话)

答案 6 :(得分:0)

嗯,据我所知,有一个巨人

while(true){}

循环操作系统旋转。您的流程在该循环内进行管理。它允许外部代码以块的形式直接在处理器上执行。不夸张地说,这是对实际情况进行简单的简化。

答案 7 :(得分:0)

  1. CPU没有被挂起&#39;它只是在峰值容量下运行,这意味着它每秒处理尽可能多的指令。 计算CPU使用率的过程是其中一些说明。如果应用程序尝试以比CPU更快的速度执行操作,那么它们就会被延迟,因此会挂起来。

  2. CPU利用率的计算基于总可用利用率。因此,如果CPU有两个核心,一个核心使用率为30%,另一个核心占60%,则整体利用率为45%。您还可以查看每个核心的使用情况。