如何计算CPU使用率?
在我的桌面上,我有一个小部件告诉我当前的CPU使用情况。 它还显示了我的两个核心的使用情况。
我总是想知道,CPU如何计算它的处理能力有多less? 另外,如果CPU挂起来做一些激烈的计算,它怎么能(或者处理这个活动)检查使用情况,而不是挂起来呢?
CPU不会自行进行使用情况计算。 它可能有硬件function,使这项任务更容易,但它主要是操作系统的工作。 所以显然实现的细节会有所不同(特别是在多核系统的情况下)。
总的想法是看看CPU需要做多less事情。 操作系统可能会定期查看调度程序以确定必须执行的操作的数量。
这是执行所述计算的Linux(从维基百科撕下)的函数 :
#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); } }
至于你的问题的第二部分,大多数现代操作系统是多任务的 。 这意味着操作系统不会让程序占用所有的处理时间,也没有任何处理时间(除非你这样做) 。 换句话说,即使应用程序出现挂起,操作系统仍然可以为自己的工作偷走一些时间。
有一个特殊的任务叫做空闲任务,当没有其他任务可以运行时运行。 %使用率只是我们没有运行闲置任务的时间百分比。 操作系统将保持运行空闲任务花费的时间总计:
- 当我们切换到空闲任务时,设置t =当前时间
- 当我们离开闲置任务时,将(当前时间 – t)添加到运行总数
如果我们把两个运行总时间的样本分开n秒,我们可以计算出运行空闲任务所花费的n秒的百分比(第二个样本 – 第一个样本)/ n
请注意,这是操作系统所做的,而不是CPU。 CPU级别上不存在任务的概念! (实际上,空闲任务会使处理器通过HLT指令进入睡眠状态,因此CPU知道它何时不被使用)
至于第二个问题,现代操作系统是抢先多任务的,这意味着操作系统可以随时切换你的任务。 操作系统是如何从您的任务中窃取CPU? 中断: http : //en.wikipedia.org/wiki/Interrupt
要获取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上,如果您想使用总共使用或空闲CPU时间的快捷方式,则可以使用GetProcessTimes或GetSystemTimes 。
其中一种方法如下:
选取一个采样间隔,例如每隔5分钟(300秒)的实际经过时间。 你可以从gettimeofday
得到这个。
获得你在300秒内使用的过程时间。 你可以使用times()
调用来获得这个。 这将是new_process_time - old_process_time
,其中old_process_time
是从上次时间间隔中保存的进程时间。
那么你的cpu百分比是(process_time/elapsed_time)*100.0
你可以设置一个闹钟来每隔300秒发出一个信号来进行这些计算。
我有一个过程,我不想使用超过一定的目标CPU百分比。 这种方法工作的很好,并与我的系统监视器很好地吻合。 如果我们使用太多的CPU,我们睡一会儿。
那么,就我所知,这里有一个巨人
while(true){}
循环操作系统旋转起来。 您的stream程是在该循环内进行pipe理的。 它允许外部代码直接在处理器上执行。 不夸张地说,这是对实际发生的事情的超级简化。
这是我对类似的代码有一点点暴露的基本理解。 像任务pipe理器或你的小工具访问系统的程序调用像NtQuerySystemInformation(),并使用从操作系统收集的信息,以简单计算一个CPU空闲或正在使用的时间百分比(在标准时间内)。 CPU知道它什么时候处于空闲状态,因此可以确定它何时不是空闲的。 这些程序确实可能会堵塞…我的笔记本电脑的任务pipe理器冻结所有的时候,当计算CPU使用率时,它是100%的顶部出。
在MSDN网站上可以find很酷的示例代码,它显示了计算一组指令的CPU使用率的函数调用: http : //msdn.microsoft.com/en-us/library/aa364157( VS.85) .aspx
这些系统调用所做的是访问内核代码,我相信…这超出了我的理解范围。
有很多方法可以做到这一点:
处理器维护几个衡量性能的计数器,您可以使用Papi接口访问它们。 例如这里是一个简要的介绍: http : //blogs.oracle.com/jonh/entry/performance_counter_generic_events
另外: http : //www.drdobbs.com/tools/184406109
您可能需要的计数器是PAPI_TOT_CYC,这是繁忙周期数(如果我没有记错的话)