まことにすみませんが、最近気づいたことがありましたので
質問させていただきます。
CPUの稼動率の取得がいつの間にかおかしくなってしまいました(あまり気にしていなかったもので)
ノートパソコンxp(Web用の小型)では0%
タワーPCWin7では100%オーバが出ます。
これってハードもしくは、OSの問題なのでしょうか?
//CPU使用率、算出処理の初期化
// HQUERY m_hQuery; //クエリーのハンドル
// HCOUNTER m_hCounter; //結果のカウンタのハンドル
void CCpuInfo::GetRateofuseInit()
{
static char *CounterPass = "\\Processor(_Total)\\% Processor Time";
PdhOpenQuery(NULL, 0, &m_hQuery);
PdhAddCounter(m_hQuery, CounterPass, 0, &m_hCounter);
PdhCollectQueryData(m_hQuery);
}
//今回、前回での情報で使用率を算出(算出間隔は上位アプリで調整)
//double版
//マイナス値の場合、初期化していない[GetRateofuseInit()を先に呼ぶこと!]
double CCpuInfo::GetRateofuseData()
{
if(!m_hQuery) return -1.0;
PDH_FMT_COUNTERVALUE Value;
PdhCollectQueryData(m_hQuery);
PdhGetFormattedCounterValue(m_hCounter, PDH_FMT_DOUBLE, NULL, &Value);
return Value.doubleValue;
}
Win2000 & VISTAでは問題なさそうでした。(デスクトップ)
HQUERY hQuery;
HCOUNTER hCounter;
PDH_FMT_COUNTERVALUE FmtValue;
PdhOpenQuery(NULL, 0, &hQuery);
PdhAddCounter(hQuery, _T("\\Processor(_Total)\\% Processor Time"), 0, &hCounter);
for(int i=0;i<20;i++){
PdhCollectQueryData(hQuery);
Sleep(1000);
PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, NULL, &FmtValue);
TRACE(_T("CPU使用率: %f%%\n"), FmtValue.doubleValue);
}
PdhCloseQuery(hQuery);
return ;
winxp(x86)、vista(x64)、win7(x86) でも特に問題は無さげだった。
volatile static bool loop_;
void __cdecl counterThread(void* param) {
_TCHAR path[_MAX_PATH];
PDH_COUNTER_PATH_ELEMENTS cpe = { 0 };
cpe.szObjectName = _T("Processor");
cpe.szInstanceName = _T("_Total");
cpe.dwInstanceIndex = -1;
cpe.szCounterName = _T("% Processor Time");
DWORD length = _MAX_PATH;
::PdhMakeCounterPath(&cpe, path, &length, 0);
HQUERY query;
::PdhOpenQuery(NULL, 0, &query);
HCOUNTER counter;
::PdhAddCounter(query, path, 0, &counter);
::PdhCollectQueryData(query);
while (loop_) {
::Sleep(1000);
::PdhCollectQueryData(query);
PDH_FMT_COUNTERVALUE value;
::PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE,NULL, &value);
_TCHAR t[32];
_stprintf(t, _T("\n%3.3f"), value.doubleValue);
DWORD written;
::WriteConsole(::GetStdHandle(STD_OUTPUT_HANDLE), t, _tcslen(t), &written, NULL);
}
::PdhRemoveCounter(counter);
::PdhCloseQuery(query);
_endthread();
}
void __cdecl stressThread(void* param) {
while (loop_) {
for (volatile DWORD dw=0; dw < DWORD(param); ++dw) ;
::Sleep(10);
}
_endthread();
}
int _tmain() {
_tsystem(_T("pause")); // start
loop_ = true;
_beginthread(&counterThread, 0, NULL);
_beginthread(&stressThread, 0, (void*)5000000); // 5000000 は適当値
_tsystem(_T("pause")); // end
loop_ = false;
::Sleep(1000);
return 0;
}
みなさんありがとうございます。
明日の昼休み実験してみます。
追加したモジュールが悪さしている気がしてきました・・・・
SpyBot-S&Dを常駐させていると、最初の10秒くらいは
CPU100%になってました。
あと
>"\\Processor(_Total)\\% Processor Time";
>"\\Process(_Total)\\% Processor Time";
ってことはないですよね?
別のPCでちょっと実験してみました、XPのノートPC
どうも、サンプリング間隔で違いが出ますね、150%オーバは多分これです
ハードウエアの速度に関係がありそうです(あくまでも予想、15分ほどでしたので)
と、ここまでは少し納得したのですが。
家のWebノートは相変わらず0%・・・
Webノートでコンパイルしてるからなのかなぁ。
しかし、間隔を算出する手段はどうしてるのだろう、という疑問も出てきてる気がする。
負荷でクロックが変わる設定だと出るかもしれませんね。
勿論未確認。
ノートの方は分かりません。管理ツールのパフォーマンスモニタが
0でないなら他のアプローチがあるのかもです。
私の知らない領域になりそうなのでROMに戻ります。頑張って下さい。
Win7での150%の原因は解決したのでとりあえずここまでとしておきます。
みなさま、ありがとうございます。
Webノートの方はPdhCollectQueryData()でPDH_NO_DATAが出ていました。
”有効ではありませんということです”、別の切り口はあると思いますが
とりあえず棚上げということで。
またこんど、よろしくお願いします
忘れてました!
ツイート | ![]() |