各CPU / Core 毎のProcessor Time を取得する(C#)
CPU メーターっぽいのを作らないといけないニーズが発生。
で、とりあえず
こんな感じのができました(試作段階なので・・・見た目が悪いのは勘弁です)。
黄色っぽいのが_Total で、青は各Core。私のマシンはCorei5なので4つ。
レンダリングにはWPFを利用。余談ですが、Silverlight からはパフォーマンスカウンタにはアクセスできないのでWPFというわけです・・・。
が、WPFはさておき、パフォーマンスカウンタ周りで思ったより(調べものに)苦労しましたので情報共有。
最初、「まあ、パフォーマンスカウンタからProcessor Time を取ってきてビジュアライズすればいいんでしょ」とヨユーをこいていたら、思わぬ落とし穴が・・・。
今回の仕様(勝手に自分で設定)を満たすためには、各CPU、各コア毎のProcessor Time を取得しなければならない・・・。
が、
Bing先生に聞くも、、、
CPUトータルのサンプルしか見つからない。
あれこれ試した結果、
//CPU(Core)数を取得
cpu_num = System.Environment.ProcessorCount;
pc = new PerformanceCounter[cpu_num];
for (int i = 0; i < cpu_num; i++)
{
string machineName = ".";
string categoryName = "Processor Information";
string counterName = "% Processor Time";
string instanceNmae = "0," + i.ToString(); //ダサイ・・・
pc[i] = new PerformanceCounter(
categoryName, counterName, instanceNmae, machineName);
}
//Tickとかループとかで値取得
value = pc[i].NextValue();
こんな感じで取得できることが判明(抜粋なので、上記コピペでは動きません。念のため)。
まず、ハマりポイントは、カテゴリー名を
Processor
ではなく
Processor Information
にしなくてはならないということ。この2つ、エイリアス程度にしか考えておりませんでしたが、違うのですね(知らないのは俺だけか?)。
で、インスタンス名は、普通、_Total かIdleくらいしか使いませんが、
1個目のCPUの1個目のコアは
0,0
というインスタンス名で取得できることがわかりました。
まあ、とりあえず、一見落着なのですが、
物理CPUとCoreを別々に取得する方法が見つからず・・・・(誰か知ってたら教えてください!)。
ということで、今のところ、CPU構成とかのわかっているマシンにしか適用できない・・・。
おまけ
開発中、CPUの負荷が全体で数%しかなくて、表示のデバッグに苦労したのですが、安定した負荷を与えるツールとしてPrime95というのを利用してみましたが、なかなか良いです。そっちの系の人には有名なツールのようですが・・・。
こんな感じで、100%負荷をかけて、ちゃんとバーのスケールが合ってるかとかチェックできるので便利でした。