トップページ > 記事閲覧
ループ時の処理負荷軽減方法
名前:チップ 日時: 2015/02/15 08:24

いつもお世話になっております。 質問させてください。 リフレッシュレートの値に左右されずに1/60で動作させるために サンプルにもある下記の方法で秒間60フレームを実装しているのですが、 //--------------------------------------------------------------------------- // 裏画面の内容を表画面に反映させる ScreenFlip() ; // 17ミリ秒(約秒間60フレームだった時の1フレームあたりの経過時間) // 経過するまでここで待つ while( GetNowCount() - Time < 17 ){} //--------------------------------------------------------------------------- CPUの占有率を見ると while( GetNowCount() - Time < 17 ){} で待っているところで処理時間を莫大に食ってしまうようです。 なるべく処理負荷をかけずにこの部分を実装する方法はございますでしょうか。 何卒宜しくお願いします。
メンテ

Page: 1 | 2 |

Re: ループ時の処理負荷軽減方法 ( No.1 )
名前:WISTERIA 日時:2015/02/15 09:20

通常は、ScreenFlip()内で1フレームの時間を調整されているので、 明示的にそのような処理は必要ありませんよ。 SetWaitVSyncFlag(FALSE);としていた場合は必要ですが。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.2 )
名前:チップ 日時:2015/02/15 09:37

ご返答ありがとうございます。 そのままScreenFlip()を使うとモニターのリフレッシュレート設定が120Hzなどになっていた場合に倍速で動いてしまうと思うのですが・・・。 動作環境になるべく依存せずに秒間60フレームを保障したいのです。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.3 )
名前:WISTERIA 日時:2015/02/15 09:45

そういうことであればSetWaitVSyncFlag(FALSE);として、 時間を待つ処理を記述すれば良いと思います。 むしろ、動きを○px/フレームとするよりも、 ○px/秒基準で動かしたほうが、スペックの低い (1秒間で60回も画面更新できないような)環境でも、 動く速さは一定にできますよ。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.4 )
名前:Nameless 日時:2015/02/15 09:51

個人的にはSetWaitVSyncFlag(FALSE)はあまりお勧めできません。 「処理負荷をかけずに」というのはなるべくCPUに負荷をかけずにという事でよろしいでしょうか? だとしたら while( GetNowCount() - Time < 17 ){Sleep(1);} で多少リフレッシュレートが前後するかもしれませんが あまりCPUを使わずに、ほぼ1/60で一定にすることができます。 もし、今からソースを可変フレームレート用に変えるのがきついという事であれば、 こちらも試されてはどうでしょう。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.5 )
名前:チップ 日時:2015/02/15 10:00

>むしろ、動きを○px/フレームとするよりも、 >○px/秒基準で動かしたほうが、スペックの低い >(1秒間で60回も画面更新できないような)環境でも、 >動く速さは一定にできますよ。 モーションで動かす3Dゲームの場合はそれでいいと思うのですが アニメーションを見せたいソフトなのでコマが飛んだり1フレーム分の表示時間が変動するのは極力避けたいのです。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.6 )
名前:チップ 日時:2015/02/15 10:08

>Namelessさん while( GetNowCount() - Time < 17 ){Sleep(1);} で試してみましたが処理が安定しなくてガクガク動いてしまうようです・・・。 ゲームループ内でもそれなりの処理をしているので一律の1秒ウェイトは無理のようです。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.7 )
名前:WISTERIA 日時:2015/02/15 10:13

まあ確かに垂直同期は取るべきものですよね。 でもやはり可変フレームレートの方がいいとは思いますが
メンテ
Re: ループ時の処理負荷軽減方法 ( No.8 )
名前:Nameless 日時:2015/02/15 10:15

ガクガク動くとなるとそもそも処理時間の調整云々以前に フレームレートが60確保できないのではないでしょうか? 簡単な確認として17を34に変えてみたりしてください。 これでガクガクが収まったらフレームレートが足りていないという事になります。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.9 )
名前:チップ 日時:2015/02/15 10:19

ゲームループ内の処理は1/60で確保できてます。 単純にSleep(1);で1秒ウェイトを待つので それ以外で例えば5%なり10%処理を食っていればすぐに処理落ちしてしまっているのではないかと思うのですが。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.10 )
名前:WISTERIA 日時:2015/02/15 10:27

>>5 処理落ちが発生した場合のコマ落ちは仕方ないですが、 アニメーションでも、 同じことができると思います。 (GetNowCount()-Time)/17 アニメーションフレームだけゲームループ毎に進めればいいと思います。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.11 )
名前:チップ 日時:2015/02/15 10:29

WISTERIAさんが可変フレームレートにこだわるのはわかるのですが やはりソフトのタイプで適正はケースバイケースだと思います。 例えば2Dの強制スクロールタイプのゲームで描画を可変にしても 滑らかに動くフレームとコマ落ちするフレームが混在してむしろ遊ぶ側からは混乱が大きいです。 その中でアニメーションだけが固定フレームで動いても違和感があります。 3Dでカメラが回るようなものなら私も可変フレームの方がいいと思うのですが。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.12 )
名前:Nameless 日時:2015/02/15 11:04

>>9 うーん。 フレームレートが足りているとなるとSleep関数の精度が足りていないのでしょうか? とりあえず精度を上げるために timeBeginPeriod(1); while( GetNowCount() - Time < 17 ){Sleep(1);} timeEndPeriod(1); としてみてください。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.13 )
名前:WISTERIA 日時:2015/02/15 10:56

確かに一概に言えないでしょう。 今回は環境(フレームレートや処理速度)に関わらず、 一定の速度で動作させたいとのことでしたので、 可変をオススメした次第です。 これを問題だと思うかどうかもそれぞれですが、 固定フレームレートですと、例えば120fpsで動くハイスペックな環境と、 処理落ちしまくりで60fpsなんて話にならない環境では、 速度や難易度の差が大きくなってしまうとおもいます。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.14 )
名前:チップ 日時:2015/02/15 11:06

すみません、 timeBeginPeriod(1); timeEndPeriod(1); ってヘッダは何になりますでしょうか? #include <mmsystem.h>ではないようなので・・・
メンテ
Re: ループ時の処理負荷軽減方法 ( No.15 )
名前:WISTERIA 日時:2015/02/15 11:07

mmsystem.h 内で宣言とありますが、エラー出ますか msdn.microsoft.com/ja-jp/library/cc428791.aspx
メンテ
Re: ループ時の処理負荷軽減方法 ( No.16 )
名前:Nameless 日時:2015/02/15 11:15

私の環境(VC++2013)では #include <mmsystem.h> #pragma comment( lib, "winmm.lib" ) でコンパイルできました。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.17 )
名前:チップ 日時:2015/02/15 11:48

情報ありがとうございます。コンパイル通りました。 ただ、やはり処理落ちするようですね。 while( GetNowCount() - Time < 17 ){Sleep(1);} の行がない場合はスムーズに動作するのですが・・・。うーん。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.18 )
名前:Nameless 日時:2015/02/15 12:17

int wait_time = Time + 17 - GetNowCount(); if(wait_time > 0){ WaitTimer( wait_time ); } とかでもダメでしょうか? だとしたら私はこれ以上の解決法を思いつきません...。
メンテ
Re: ループ時の処理負荷軽減方法 ( No.19 )
名前:チップ(解決) 日時:2015/02/15 15:03

Nameless さん なるほど、WaitTimer()を使えばよかったんですね! 解決しました!色々ありがとうございました。
メンテ

Page: 1 | 2 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存