メインスレッドはまわらない、Sleep、割り込み、コンテキストスイッチ。

プログラム書いてるよー。

カタカタカタ、ターンを続けてフェーズ1は実装完了。

メッセージを記録するキューは、そもそも3メッセージくらいで動いているアプリケーショになるのでいらなかった説。ううむ。
統合時に考えよう。
テストまで作ったのにー。

それでも60分の1秒を目指す

実装過程でメインスレッドを60分の1秒でまわす機能があるのですが、これがうまくまわっていないことに気づきました。

実装自体はそんなに特殊ではないので別段エラーも起こさずに素直に動きます。
のですが、動作確認のために時間を計測してみるとどうもヘンテコな数字があがって。

時間の計測は、A地点からB地点までにかかった時間を測るといった内容になります。
A地点で実行されるコードの前で現在時刻を記録して、B地点に来たところで再度時間を計測、その差を処理時間として観察。

メインスレッドでは1周の処理の時間を均一にするため、余った時間スレッドを休眠させている。
どうも使用しているSleep命令の復帰時間が怪しいかも。

メインループのフロー
※問題が起きているのは赤い箇所。

寝起きまでの時間が余分にかかっているような数字?
わたしも寝起きはよい方ではないけれど、とりあえずAPI仕様を読んでみる。

はて?そこまで使い方を間違っているわけではなさそうです。
引数1つですし。

ちょっと気になるのは以下の部分ですが、短くではなく長くなっています。(読み間違えてるのかな?)
「 If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time.」
 
いくつかの方法も試してみたのですが、どうにも数字が安定しません。
試したところでは1ミリ秒待つということすら満足にできない有様。
10ミリ秒以上命令から返ってきません。

流石にアクションゲームに取り掛かる際には致命的。

仕方ないのでネットで検索。
ワードは「Windows」と「Sleep」と「C++」と「精度」あたり。

類似報告がばんばんでる。
ううーん。

どうもOSの仕様としてWindowsは通常のサービスとしてSleepの精度を低くしてあるのかな?
これには理由があって、メーカーごとのハード実装、OSの実装都合、精度をあげると割り込み回数があがりCPUの使用率があがってしまうみたい。
必然的に全体の動作に負担がかかり消費電力もあがり。
たぶん、これを嫌っているのかな。

回避策として全プロセス向けとして精度を上げるAPIを用意しているそうですが、注意して使うようにとのこと。
確かに精度をあげるAPIに関してはドキュメントに書いてありました。
流石に全プロセスの割り込み速度をいじるなんてできないよね。

調べていないので予想ですが、たぶんデスクトップ・アプリケーションでそこまでタイマー精度を求めるアプリケーションは作らないでね、ということかも。
WindowsにはDirectXというマルチメディア向けの命令セットが用意されていますので、本来はそちらを使うべき?
ユニバーサル系のフレームワークだとまた違うのかな。

これの結論は次の課題。
もう少し気軽に転がしておけるアプリケーションを目論んだのですが、絵をアニメーションさせる的なリッチな方向に進む場合何か手を考えないと。

今回はここまで。
恐らくドキュメントのこのあたりにヒントがあって。
「After the sleep interval has passed, the thread is ready to run. If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready.」

「時間を0で指定するとコンテキスト・スイッチがかかり、他のスレッドにCPUが移る。
自スレッドは寝てないけれど、いつCPUが戻ってくるかはわからないよ。」

と、書いているような気がしました。

であればCPUを回したままにならず、他のスレッドにCPUを移せるかな。
戻ってくるたびに時間を取得して終了を判断すれば、Sleepで時間指定をするガバガバ待ちよりは精度をあげることができるかも。

で、こんなコードを書いて実験。

フェーズ1:基礎エンジンの実装

うーん。
見た限りCPUの使用量が20%ちょい上。

開発機はセロリン4コアなので1コアをガメっぱなしな感じに。
なんとかしたいけれど、ひとまずはメインスレッドを設けるとこのくらいCPUを使う。
時間も計測してみましたが、少しフラつくこともありますが最初よりは落ち着いた結果です。
たまに余分に時間を食う分は、次の周回の待ち時間から引いて調整するようにしているのでなんとか。
 
 
ここで、セロリン4コアっておかしくない?と気になった貴方は自作PC派の方!

デスクトップ向けセロリンは確か2コアまでなんですよね。
上にPentiumがいるからスレッドも2までに制限される始末。

開発に使っているPCはノート向けのボードが載っているものなので、セロリン4コア4スレッドというヘンテコ仕様なのです。
中身はAtomチップですね。
出来る子なのでお気に入り。

さあ、次はフェーズ2。がんばる。