デスクトップには、現在のCPU使用率を示す小さなウィジェットがあります。また、2つのコアそれぞれの使用法も示しています。
CPUは、処理能力のうちどれだけが使用されているかをどのように計算するのでしょうか?また、CPUがかなりの計算を行ってハングアップした場合、どのように(またはこのアクティビティを処理するものでも)ハングアップすることなく使用状況を調べることができますか?
CPUはそれ自体で使用量の計算を行いません。そのタスクを容易にするハードウェア機能を備えている場合がありますが、ほとんどはオペレーティングシステムの仕事です。したがって、実装の詳細は明らかに異なります(特にマルチコアシステムの場合)。
一般的な考え方は、CPUが実行する必要があるもののキューがどれくらいの長さであるかを確認することです。オペレーティングシステムは、スケジューラを定期的に調べて、実行する必要がある処理の数を判断する場合があります。
これは、上記の計算を実行する(Wikipediaからリッピングされた)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);
}
}
質問の2番目の部分については、最新のオペレーティングシステムのほとんどは マルチタスク です。つまり、OSはプログラムがすべての処理時間を占有することを許可せず、それ自体のために何も持たないことを意味します (あなたがそれを行わない限り) 。つまり、アプリケーションがハングしているように見えても、OSはstill自身の作業のためにしばらく時間を奪います。
他のタスクを実行できないときに実行されるアイドルタスクと呼ばれる特別なタスクがあります。使用率は、アイドルタスクを実行していない時間の割合です。 OSは、アイドルタスクの実行に費やした時間の合計を維持します。
実行中の合計の2つのサンプルをn秒離すと、アイドルタスクの実行に費やされたn秒の割合を(2番目のサンプル-最初のサンプル)/ nとして計算できます
これは、OSではなくCPUが行うことに注意してください。タスクの概念は、CPUレベルには存在しません! (実際には、アイドルタスクはHLT命令でプロセッサをスリープ状態にするため、CPUは使用されていないことを認識します)
2番目の質問については、最新のオペレーティングシステムは先制的にマルチタスクです。つまり、OSはいつでもタスクから切り替えることができます。 OSは実際にタスクからCPUをどのように盗み出しますか?割り込み: http://en.wikipedia.org/wiki/Interrupt
CPU使用率を取得するには、定期的にtotalプロセス時間をサンプリングし、差を見つけます。
たとえば、これらがプロセス1のCPU時間である場合:
kernel: 1:00:00.0000
user: 9:00:00.0000
そして、2秒後に再び取得します。
kernel: 1:00:00.0300
user: 9:00:00.6100
カーネル時間を減算します(0.03
)およびユーザー時間(0.61
)、それらを一緒に追加します(0.64
)、2秒のサンプル時間(0.32
)。
そのため、過去2秒間で、プロセスは平均32%のCPU時間を使用しました。
この情報を取得するために必要な特定のシステムコールは、(明らかに)すべてのプラットフォームで異なります。 Windowsでは、totalのショートカットを使用する場合は GetProcessTimes または GetSystemTimes を使用できます。またはアイドルCPU時間。
その方法の1つは次のとおりです。
実際の経過時間の5分(300秒)ごとにサンプリング間隔を選択します。これはgettimeofday
から取得できます。
その300秒で使用した処理時間を取得します。これを取得するには、times()
呼び出しを使用できます。それはnew_process_time - old_process_time
、ここでold_process_time
は、最後の時間間隔から保存した処理時間です。
CPUパーセンテージは(process_time/elapsed_time)*100.0
これらの計算を行うために、300秒ごとに通知するアラームを設定できます。
特定のターゲットCPUパーセンテージを超えて使用したくないプロセスがあります。この方法は非常にうまく機能し、私のシステムモニターとよく一致します。 CPUの使用量が多すぎる場合は、少し寝ます。
これは、同様のコードに少し触れることからの私の基本的な理解です。タスクマネージャーやウィジェットなどのプログラムは、NtQuerySystemInformation()などのシステムコールにアクセスし、OSから収集された情報を使用して、CPUがアイドル状態または使用されている時間の割合を簡単に計算します(標準時間内)。 CPUはアイドル状態を認識しているため、アイドル状態でないことを判断できます。これらのプログラムは実際に詰まる可能性があります...私のラップトップのタスクマネージャーは、CPU使用率が100%を超えたときに計算すると、常にフリーズします。
一連の命令のCPU使用率を計算するための関数呼び出しを示すコードのサンプルコードは、MSDNのWebサイトにあります。 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です(私が正しく覚えている場合)
まあ、私が理解している限り、巨大な
while(true){}
オペレーティングシステムが起動するループ。プロセスはそのループ内から管理されます。これにより、外部コードをプロセッサで直接チャンクで実行できます。誇張しすぎることなく、これは実際に行われていることを非常に単純化したものです。
CPUは「ハング」することなく、単にピークキャパシティで動作します。つまり、物理的に毎秒可能な限り多くの命令を処理しています。 CPU使用率を計算しているプロセスは、これらの命令の一部です。アプリケーションがCPUの能力を超える速度で操作を行おうとすると、単純に遅れてしまい、「ハングアップ」します。
CPU使用率の計算は、使用可能な合計使用率に基づいています。したがって、CPUに2つのコアがあり、1つのコアの使用率が30%で、もう1つのコアの使用率が60%の場合、全体的な使用率は45%です。各コアの使用状況も確認できます。