StopWatchクラス使用上の注意

単純な(=動作クロックに対してリニアに処理時間が変わる)数値計算を行っていたのですが、StopWatchクラスを用いて処理時間を計測したところ、CPUの動作クロックを任意に変更(1GHz〜2GHz)しても、計った処理時間がほとんど変わらない、という問題に遭遇しました。
OSはWindows2000、CPUがAthlon64X2、動作クロックをCrystalCPUIDを用いて変更していたのですが、この類のソフトウェアを使ってOSが想定していない形で動作クロックを変更しているのが原因でないかなぁと最初は思いまして、、、

処理時間が同じとなる原因の推測

たとえば2000Clockかかる処理があったとして
動作クロックが2GHzであれば1周期に相当するので、これの処理時間としては1secが返されると考えられます。
しかし、この状態で動作クロックを1GHzに変更すると、OS側は1周期 = 2000Clockと認識したままなので、2000Clockかかる処理を、1secと返してしまうのではないでしょうか。(本来なら1GHzでの1周期は1000Clockなので、2000Clockの処理は2secに相当)

ってことで、これはStopWatchクラスが内部で用いているQueryPerformanceCounter関数*1の問題かなとさらに推測しまして、試しにQueryPerformanceCounter関数についてググってみたら・・・

クロック周波数の測定手法
http://crystalmark.info/special/clock.html

CrystalCPUIDの作者様がその辺の話をガッツリまとめられていました。あ、、、やっぱりCPU周り弄られていたら、こんな初歩的なこと気付きますよね↓↓↓色々データとって調べたの無駄だったじゃん、とか思ったら大幅にテンション下がった・・・orz
ま、それはさておき。上記記事の追記部分見てると、MSDNからの引用で

QueryPerformanceFrequency
高分解能パフォーマンスカウンタが存在する場合、そのカウンタの周波数(更新頻度)を取得します。システムが動作している間は、周波数を変更できません。

ってのが・・・。なんかまるで、OS動作中は動作クロックは変更できないんだぜ、fu*k u!みたいな感じがしてイヤですね、この和訳。何をどう間違ってこんな訳になったのか気になったので、USの原文をあたってみると

QueryPerformanceFrequency Function
The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists. The frequency cannot change while the system is running.

相変わらず英語は無駄なく機能的に書かれてるなぁ、って感想はさておき、最初のfrequencyはカウント回数ぐらいの意味かなぁ・・・。いや、どっちでもいっか。2文目の"The" frequencyは、このQueryPerformanceFrequencyのことだよなぁ・・・。日本語訳、気を利かせて「QueryPerformanceFrequencyの値は」ぐらいにしとけばいいのに。単に周波数って言うと、動作クロックのことかと思うじゃん(俺だけ?

[C++]Windowsで細かく時間を計測する
http://d.hatena.ne.jp/toge/20050809#1123866064

あとは、ここにもQueryPerformanceFrequencyの話が出てたので捕捉。んー、XP以降のOS標準の機能(CPUドライバ)でクロックを可変させてる場合は、ちゃんとした値が返ってくるのかなぁ?謎。
とりあえず、今後処理時間計測するときは、処理時間を長めにしてやって、Environment.TickCountかDateTime.Nowの差分とって手っ取り早く済ませとこうかなと(振り出しに戻った・・・orz)

*1:計測精度がCPUの周波数依存。周波数に依存ってとこがポイント?