CPU稼働率がうまく取れなくなってしまいました。

解決


眞鋳  2011-02-27 01:45:57  No: 72376

まことにすみませんが、最近気づいたことがありましたので
質問させていただきます。

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


とりがら  2011-03-01 01:53:11  No: 72377

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 ;


gak  2011-03-01 03:07:11  No: 72378

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


眞鋳  2011-03-01 05:53:13  No: 72379

みなさんありがとうございます。

明日の昼休み実験してみます。
追加したモジュールが悪さしている気がしてきました・・・・


とりがら  2011-03-01 08:13:43  No: 72380

SpyBot-S&Dを常駐させていると、最初の10秒くらいは
CPU100%になってました。

あと
>"\\Processor(_Total)\\% Processor Time";
>"\\Process(_Total)\\% Processor Time";
ってことはないですよね?


眞鋳  2011-03-02 08:59:31  No: 72381

別のPCでちょっと実験してみました、XPのノートPC
どうも、サンプリング間隔で違いが出ますね、150%オーバは多分これです
ハードウエアの速度に関係がありそうです(あくまでも予想、15分ほどでしたので)
と、ここまでは少し納得したのですが。

家のWebノートは相変わらず0%・・・
Webノートでコンパイルしてるからなのかなぁ。

しかし、間隔を算出する手段はどうしてるのだろう、という疑問も出てきてる気がする。


とりがら  2011-03-02 09:38:12  No: 72382

負荷でクロックが変わる設定だと出るかもしれませんね。
勿論未確認。

ノートの方は分かりません。管理ツールのパフォーマンスモニタが
0でないなら他のアプローチがあるのかもです。
私の知らない領域になりそうなのでROMに戻ります。頑張って下さい。


眞鋳  2011-03-06 07:14:00  No: 72383

Win7での150%の原因は解決したのでとりあえずここまでとしておきます。
みなさま、ありがとうございます。

Webノートの方はPdhCollectQueryData()でPDH_NO_DATAが出ていました。
”有効ではありませんということです”、別の切り口はあると思いますが
とりあえず棚上げということで。

またこんど、よろしくお願いします


眞鋳  2011-03-06 07:15:12  No: 72384

忘れてました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加