2012/12/31(月)WindowsPCで時計の進みが遅くなる現象に遭遇した
おおみそかだよどらえもん
2013.01.01 本記事の取り消し線部分は誤り。追記を参照してください
今日はPCにまつわる時計の話。時計と言うよりはタイマの話。
時間が正確に測れないパソコンがある。
というか、僕のメインマシンであるデスクトップがそう。
(2013.01.01 訂正)PCの時計の進みが遅くなるという現象に遭遇したので記録しておく
症状は VSyncな60fpsゲームでFPSを表示させると61.8fpsと出るというもの。
オーバークロックによってベースクロックを103%にしているが、60*1.03=61.8 である。
音ゲーしててもBGMとキー音がずれる。
時計の進み方が遅い。考えたこともなかったが、それは本当か?
実際、DateTime.Now の値を画面に表示して手元の腕時計と比較してみると、
なんと1分に2秒ずつ遅れていくことに、今回初めて気がついた。
進みが遅い時計もひどいが、今まで気づかなかった自分もなかなかひどいなぁ……。
# このままだと、システム時計が1日48分遅れる計算になるが、それはさすがに気づくはずだし、
# 今まで気がつかなかったのは、裏で時刻がよしなに同期されてるんだろうなぁ。
(2013.01.01 追記ここから)
PCのベースクロックを変更した後、Windowsを"再起動"していなかったのが原因。
と、書くとあほかと思われるので事情も弁明しておく。
上で挙げた時計の進みが現実時間に合わなくなる問題は、
シャットダウン → 電源ON → クロック変更 → そのまま起動 した場合に発症し、
再起動 → クロック変更 → そのまま起動 すると 発症しないようだ。
追検証として、発症後の再起動も試してみた。
シャットダウン → 電源ON → クロック変更 → そのまま起動 → 発症 → 再起動 → 解消
そう、もうおわかりですね!
Windows8では高速スタートアップ機能が新しく搭載された。
「再起動」コマンドを選ばない限りはずっと休止状態のような状態になるのだ。
シャットダウンだけでは、Windowsは変更されたベースクロックに気づかないようだ。
ちなみに、筆者は(再インストールがめんどくさくて)Windows 8のRPを未だに使い続けているので、
もしかするとRTMではこの問題は起こらないかもしれない、起こるかもしれない。
ちょうど期限も切れるので、入れ替えてみて追検証をしたいと思う。
また、「クロックを上げたのに時計が遅くなっている」というのは完全に勘違い。
今回の症状は103%に設定していたクロックを一時的に100%に戻したことが原因。
正しくは「クロックを103→100に落としたから、進みが100/103に遅くなった」だった。
FPSが61.8になる理にかなっている。訂正してお詫びする。
(2013.01.01 追記ここまで)
チップセットの仕様なのかマザーの仕様なのかわからないが、
さしあたっての問題は、音楽ゲームを遊ぶときBGMとキー音がじゃんじゃかずれていくことである。
ドラムが120bpmで演奏してるのにギターが126bpmで進んでいけば、それはもちろん聴くに堪えない。
さて、どこかに正確な時計はないものかー
(2013.01.02 追記)解決したのでここより下は完全に冗長な情報になってしまった
System.Diagnostics.Stopwatch と、おなじみ Win32 APIのtimeGetTime() と、
果ては QueryPerformanceCounter() も試してみたが、どれも同じ結果になってしまった。
まぁ、DateTime.Nowがずれていくぐらいだからなぁ……。
QueryPerformanceCounterで時刻を測る方法に関しては、
ネットブックであるEeePCを使っていた時にすでに 省電力設定の切り替えるだけで狂ったので、
その頃からこれに頼るのはやめているのでまぁいいとして、
今回は頼みの綱であるtimeGetTime()も正確な値を返してくれないのが困ったところ。
うーん。時計がないなら作れば良いじゃない。
というわけで、サウンドデバイスから時刻をもらってくることにする。
サウンドデバイスを開いて、1秒分のバッファを作ってループ再生しておいて、
別スレッドでループが何回回ったのかも数えておく。
時刻が欲しいときは、回った回数と現在再生しているバッファ内の位置から時刻を求める。
サウンドデバイスと時刻を同期させることで、音楽がずれることはなくなった(当然だけど)。
正確な時計を得ることができた! (2013.01.01 追記)しかし、精度が10msしかなかった
これで(2013.01.01 追記)はじめから、こんなものがなくても安心して音楽ゲームが作れる。
しかし、CPUの動作周波数が可変というのはなかなか大変な時代だ。