2010/8/22:本掲示板は閲覧専用です。データが一部破損しておりますがご了承ください。
  新規投稿 ┃ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索 ┃設定 ┃ホーム  
2197 / 2351 ←次へ | 前へ→

【156】Re:クロック周波数測定の問題点について
←back ↑menu ↑top forward→
 ひよひよ  - 03/6/7(土) 10:54 -

引用なし
パスワード
   ▼ぬじぬじさん:
こんにちは〜 ぬじぬじさんもいつの間にやらよさげなマシンを購入したようで...正直 ぬじぬじさんと WinXP の組み合わせにちょっぴり隔世の感が(笑)

> 双方とも省電力プロセッサ(俺のが Pentium III-M で Kim さんのが Pentium M)でしかも ThinkPad X3* と云う点が共通しています。
私も SpeedStep マシンは試してみたいのですが... 研究室には Crusoe マシンがあるので、LongRun を試してみますかね。

> 修正の必要性に関して議論はあると思います。それはそれで正しい(周波数測定時の)周波数を測定してはいますから。が。GHz 当たりの速度を比較したい場合などに正しいデータが得られません。そもそもランキングの際に不公平感が漂います。ちう訳でさくっと直して頂ければありがたいです。
ユーティリティで低クロック固定で無い場合は、自動でクロックが上がっていくと思っているのですが、ずっと負荷が無い状態から CrystalMark を起動するとクロックが上がりきる前にクロックの測定が終わるということになるみたいですね。自動でクロックが上がる設定なら、ベンチ中は常時 100% の CPU パワーが活用できるわけで、確かに測定時のクロックとは異なりますな... あと、古い SpeedStep は負荷ではなく AC アダプタがつながっているかどうかでクロックが変化するそうです。

解決策としては、SpeedStep や PowerNow! や Crusoe 等の CPU のクロックが動的に変更できるプロセッサかどうかを識別し、必要に応じて、負荷をかけてから、クロック周波数を測定するという方法が考えられます。ここで問題になるのは、どの程度の時間が必要なのかという一点のみ。調べてみると、二つのモードは 0.5ms で遷移できるそうです。う〜む、本当に 0.5ms ならクロック周波数の測定には影響なさそうですが...

    QueryPerformanceCounter(&lPre);
    QueryPerformanceCounter(&lStart);
    _asm{
        rdtsc
        mov dwStartH , edx
        mov dwStartL , eax
    }
    dwStart = GetTickCount();
    
    // Sleep API だとまれに不具合が起きるため
    TickCount = GetTickCount();
    while(GetTickCount() - TickCount < SLEEP_TIME){}
    dwEnd = GetTickCount();
    _asm{
        rdtsc
        mov dwEndH , edx
        mov dwEndL , eax
    }
    QueryPerformanceCounter(&lEnd);
    QueryPerformanceFrequency(&lFrequency);

今はこんな感じでクロック周波数を取得していますが、SpeedStep 的には
    while(GetTickCount() - TickCount < SLEEP_TIME){}
の部分が負荷のうちに入っていないのかもしれません。無限ループの中に無意味な内容の計算でも入れれば、うまくいくのかな?ちなみに現在の SLEEP_TIME は 500 ms と定義しています。(もっと短くても平気なのですが...)

というわけで、こんな感じにしました。

// 負荷増強
    volatile int i=0; // 最適化対策のつもり
    if( FlagClockModulation ){
        TickCount = GetTickCount();
        while(GetTickCount() - TickCount < 100){
            i++;
        }
    }
// クロック測定
    QueryPerformanceCounter(&lPre);
    QueryPerformanceCounter(&lStart);
    _asm{
        rdtsc
        mov dwStartH , edx
        mov dwStartL , eax
    }
    dwStart = GetTickCount();
    
    // Sleep API だとまれに不具合が起きるため
    TickCount = GetTickCount();
    while(GetTickCount() - TickCount < SLEEP_TIME){
        i++; // ここでも無駄に...
    }
    dwEnd = GetTickCount();
    _asm{
        rdtsc
        mov dwEndH , edx
        mov dwEndL , eax
    }
    QueryPerformanceCounter(&lEnd);
    QueryPerformanceFrequency(&lFrequency);

ひょっとしら、i が最適化されて消えちゃうかも知れないけど...

とりあえず、クロック周波数測定君 (VC++ コーナー) にはほぼ同様のコードがついてるんで、そいつで、どうすれば最大クロックが取得できるか試してみるのも良いかなと。

※FlagClockModulation は SpeedStep PowerNow! LongRun 対応 CPU で TRUE です。
今回の処理を追加したバージョンを期間限定で、
http://musee.cims.hokudai.ac.jp/~hiyohiyo/SysInfo.dll においておきます。

研究室の Crusoe も試してみて良い様だったら月曜日に更新しておきます。バグ(?)報告三サンキュです。もちろん、前からわかっていたのですが、腰が重くて...(と言い訳)

285 hits

【155】クロック周波数測定の問題点について ぬじぬじ 03/6/7(土) 7:30
【156】Re:クロック周波数測定の問題点について ひよひよ 03/6/7(土) 10:54

2197 / 2351 ←次へ | 前へ→
  新規投稿 ┃ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索 ┃設定 ┃ホーム  
ページ:  ┃  記事番号:   
51982
(SS)C-BOARD v3.8(とほほ改ver2.1) is Free