FPSがうまく制御できない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
nullptr
記事: 239
登録日時: 13年前

FPSがうまく制御できない

#1

投稿記事 by nullptr » 13年前

いつもお世話になっております。FPSを垂直同期を使わずに制御するコードを簡単に書いてみましたが、なぜか59.8ほど(59.8のまま一定)になってしまいます。
タイマーはboost1_49_0のcpu_timerを使っています。どうして59.8になってしまうのでしょうか。環境はVC++2010pro、DXライブラリ使用(垂直同期は使わないよう設定)、Windows7です。
ご教授宜しくお願いします。

コード:

// 宣言と初期化まわり
const float Fps = 60.0f; // FPSは60
float Wait = 0.f;
boost::timer::cpu_timer Timer;
boost::timer::cpu_times Result = Timer.elapsed();

コード:

// ウェイトを処理 毎フレーム一回コレを通るようにしている
Result = Timer.elapsed();
if( ((float)(Result.wall)) < 1000.f/Fps*1000000.f ){
	Wait = 1000.f/Fps*1000000.f - ((float)(Result.wall));
}
else {
	Wait = 0.f;
}
if( Wait > 0.f ){
	float Start = (float)(Result.wall);
	float End = Start + Wait;
	if( fWait > 4000000.f )
	{
		while( End - 4000000.f > (float)(Timer.elapsed().wall) && !ProcessMessage() ) Sleep( 1 );
	}
	while( End > (float)(Timer.elapsed().wall) );
}
Result = Timer.elapsed();
Timer.start();
printfDx("%04.4f[FPS]",1000.f/((float)(Result.wall)/1000000.f));
最後に編集したユーザー nullptr on 2012年4月25日(水) 15:14 [ 編集 1 回目 ]
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: FPSがうまく制御できない

#2

投稿記事 by softya(ソフト屋) » 13年前

boost::timer::cpu_timerって確か15ms程度の精度しか無いと聞いたことがありますので、精度を確認してみてください。勘違いかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#3

投稿記事 by nullptr » 13年前

softya(ソフト屋) さんが書きました:boost::timer::cpu_timerって確か15ms程度の精度しか無いと聞いたことがありますので、精度を確認してみてください。勘違いかもしれません。
ご返信ありがとうございます。15ms程度の精度?というのがどういう意味なのかわかりませんが、FPS制御をするにあたり事前に様々なタイマーを試しましたが、cpu_timerは数百ナノ~数千ナノくらいの単位まで計測できました。
少なくとも、DXライブラリのGetNowCountよりも確実に精度が高く安定しており、GetNowHiPerformanceCountと同じ精度かそれ以上でした。
他にもtimeGetTimeとかも試しましたが、なぜかtimeGetTimeはやけに遅かったです。boost::chronoの方は精度もよく速度は安定していましたが、使い方がわからない点が多すぎました。

なので、cpu_timerを使っているのですが、、、

それと、おそらくcpu_timerの精度の問題では無いと思っています。念のためGetNowHiPerformanceCountや他の関数でもFPSを調べましたが、やはりどれも59.8FPSになります(GetNowCountだけは異常に不安定なFPSを表示しますが)。

// *追記

ネット上の資料によると、cpu_timer.userは15msほどの精度ですが、コードで使っているcpu_timer.wallは数百ナノで合っているようです。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#4

投稿記事 by ISLe » 13年前

boostのcpu_timerの精度は知りませんけど、floatの精度がナノ秒には足りないんじゃないですかね。

フレームごとに差分を蓄積していく方法だと浮動小数点数を使おうと誤差も蓄積していきます。
それ以外の部分が原因で下がることはありますけど、タイマーの精度が低くても振り幅があるだけでそれ自体でFPSが下がったままになるといったことはありません。

わたしのブログのFPS制御コードは参考にしなかったんですね。
GetNowCountを使っているので安定しなかったのでしょうか。

タイマーの精度は単位とは関係ありません。
精度が15ミリ秒というのは15ミリ秒ごとに15ミリ秒分ずつ値が増えるということです。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#5

投稿記事 by nullptr » 13年前

ISLe さんが書きました:boostのcpu_timerの精度は知りませんけど、floatの精度がナノ秒には足りないんじゃないですかね。

フレームごとに差分を蓄積していく方法だと浮動小数点数を使おうと誤差も蓄積していきます。
それ以外の部分が原因で下がることはありますけど、タイマーの精度が低くても振り幅があるだけでそれ自体でFPSが下がったままになるといったことはありません。

わたしのブログのFPS制御コードは参考にしなかったんですね。
GetNowCountを使っているので安定しなかったのでしょうか。

タイマーの精度は単位とは関係ありません。
精度が15ミリ秒というのは15ミリ秒ごとに15ミリ秒分ずつ値が増えるということです。
ISLeさんご返答ありがとうございます。floatの精度ですか。後でdoubleで試してみます。

>わたしのブログのFPS制御コードは参考にしなかったんですね。
いえ、考え方はとても勉強になりましたし、本当に参考になったんですが、ISLeさんのコードで垂直同期を外すフラグを立てたところ、62FPS(のまま一定)になってしまいまして。完全にコードが理解できているわけではないので、もしかしたら垂直同期を利用する上でFPSを制御するコードだったのか思い、とりあえず一旦自分なりにコードを書いてみたところ、自分のコードも思ったように動かず、理由を知りたい、という状況です。決して参考にしなかったわけでは無いんです、すみません。

>精度が15ミリ秒というのは15ミリ秒ごとに15ミリ秒分ずつ値が増えるということです。
そうだったんですか。ということは精度が15ミリの場合15ミリ秒ごとに15ミリ秒処理を早める処理が必要になるのでしょうか?
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#6

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:>わたしのブログのFPS制御コードは参考にしなかったんですね。
いえ、考え方はとても勉強になりましたし、本当に参考になったんですが、ISLeさんのコードで垂直同期を外すフラグを立てたところ、62FPS(のまま一定)になってしまいまして。完全にコードが理解できているわけではないので、もしかしたら垂直同期を利用する上でFPSを制御するコードだったのか思い、とりあえず一旦自分なりにコードを書いてみたところ、自分のコードも思ったように動かず、理由を知りたい、という状況です。決して参考にしなかったわけでは無いんです、すみません。
おかしいですね。
わたしのコードの基本部分はDirectX以外やウィンドウズ以外にも使っているので垂直同期があろうとなかろうと正確にFPSを維持できるはずです。
コードをアレンジしてないですよね?
こちらはWindows 7でウィンドウモードのAero有効・無効、フルスクリーンモードいずれでも期待どおりに動きますけど。

ディスプレイドライバの設定を弄ってますか?
あるいは古いDXライブラリを使っているとか。
新月獅子 さんが書きました:>精度が15ミリ秒というのは15ミリ秒ごとに15ミリ秒分ずつ値が増えるということです。
そうだったんですか。ということは精度が15ミリの場合15ミリ秒ごとに15ミリ秒処理を早める処理が必要になるのでしょうか?
デジタル時計の秒は1秒毎に1ずつ増えるので精度は1秒ですが1秒毎に1秒早める必要はありません。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#7

投稿記事 by nullptr » 13年前

ISLeさんお返事ありがとうございます。
ISLe さんが書きました:
新月獅子 さんが書きました:>わたしのブログのFPS制御コードは参考にしなかったんですね。
いえ、考え方はとても勉強になりましたし、本当に参考になったんですが、ISLeさんのコードで垂直同期を外すフラグを立てたところ、62FPS(のまま一定)になってしまいまして。完全にコードが理解できているわけではないので、もしかしたら垂直同期を利用する上でFPSを制御するコードだったのか思い、とりあえず一旦自分なりにコードを書いてみたところ、自分のコードも思ったように動かず、理由を知りたい、という状況です。決して参考にしなかったわけでは無いんです、すみません。
おかしいですね。
わたしのコードの基本部分はDirectX以外やウィンドウズ以外にも使っているので垂直同期があろうとなかろうと正確にFPSを維持できるはずです。
コードをアレンジしてないですよね?
こちらはWindows 7でウィンドウモードのAero有効・無効、フルスクリーンモードいずれでも期待どおりに動きますけど。

ディスプレイドライバの設定を弄ってますか?
あるいは古いDXライブラリを使っているとか。
SetWaitVSyncFlag(FALSE);を呼び出していること以外は一切アレンジはしておりません。ディスプレイドライバの設定もいじってません。DXライブラリのバージョンは3.07dです。
なぜ・・・なんでしょうか?;;
新月獅子 さんが書きました:>精度が15ミリ秒というのは15ミリ秒ごとに15ミリ秒分ずつ値が増えるということです。
そうだったんですか。ということは精度が15ミリの場合15ミリ秒ごとに15ミリ秒処理を早める処理が必要になるのでしょうか?
デジタル時計の秒は1秒毎に1ずつ増えるので精度は1秒ですが1秒毎に1秒早める必要はありません。
そうでしたか、ありがとうございます。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: FPSがうまく制御できない

#8

投稿記事 by softya(ソフト屋) » 13年前

今思いつきましたがSetWaitVSyncFlag(FALSE);をDxLIb_Init();の前に呼んでいないとかありませんよね?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#9

投稿記事 by nullptr » 13年前

softya(ソフト屋) さんが書きました:今思いつきましたがSetWaitVSyncFlag(FALSE);をDxLIb_Init();の前に呼んでいないとかありませんよね?
ご返答ありがとうございます。いえ、ちゃんとDxLib_init();の前で呼び出してありますね。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: FPSがうまく制御できない

#10

投稿記事 by softya(ソフト屋) » 13年前

DXライブラリを抜いても60FPSで安定しないんでしょうか? FPSはOutputDebugString で出力できますし。
原因をはっきりするためにも抜けるものは抜いて計測してみるとか、DXライブラリの関数(ScleepFlip等)にかかっている時間を計測してみるとか色々手はあると思います。

【追記】
あと時間計測関数自体が遅いと言うのも考えられます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#11

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:SetWaitVSyncFlag(FALSE);を呼び出していること以外は一切アレンジはしておりません。ディスプレイドライバの設定もいじってません。DXライブラリのバージョンは3.07dです。
なぜ・・・なんでしょうか?;;
わたしのFPS制御コードといっしょに配布しているサンプルプログラムにSetWaitVSyncFlag(FALSE)を呼び出すコードを加えただけということですか?
サンプルプログラムは58FPSで動くように作られています。
他にも手を加えているはずです。
手を加えた箇所を一字一句漏らさず教えてください。

ハードウェアレベルの問題かもしれません。

添付したプログラムを実行して表示されるFPSを教えてください。
FPS制御コードのサンプルプログラムをVSYNCオフで60FPSにしたものです。
こちらでは60FPSで安定します。
添付ファイル
VGTrigonometric1DxLib.zip
(954.76 KiB) ダウンロード数: 149 回

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#12

投稿記事 by nullptr » 13年前

softya(ソフト屋) さんが書きました:DXライブラリを抜いても60FPSで安定しないんでしょうか? FPSはOutputDebugString で出力できますし。
原因をはっきりするためにも抜けるものは抜いて計測してみるとか、DXライブラリの関数(ScleepFlip等)にかかっている時間を計測してみるとか色々手はあると思います。

【追記】
あと時間計測関数自体が遅いと言うのも考えられます。
DXライブラリ一切なしで№1のコードを試したところ59.9で一定でした‥‥


ISLe さんが書きました:
新月獅子 さんが書きました:SetWaitVSyncFlag(FALSE);を呼び出していること以外は一切アレンジはしておりません。ディスプレイドライバの設定もいじってません。DXライブラリのバージョンは3.07dです。
なぜ・・・なんでしょうか?;;
わたしのFPS制御コードといっしょに配布しているサンプルプログラムにSetWaitVSyncFlag(FALSE)を呼び出すコードを加えただけということですか?
サンプルプログラムは58FPSで動くように作られています。
他にも手を加えているはずです。
手を加えた箇所を一字一句漏らさず教えてください。

ハードウェアレベルの問題かもしれません。

添付したプログラムを実行して表示されるFPSを教えてください。
FPS制御コードのサンプルプログラムをVSYNCオフで60FPSにしたものです。
こちらでは60FPSで安定します。
ほんっとうにすみません、たしかに手を加えていました!!(*_*;
FPSが制御できるのか試していた時にVGCanvasのコンストラクタに与える引数を変えたままでした!!本当にすみませんでしたorz
頂いたプログラム、ちゃんと60FPSになりました。本当にご迷惑おかけしてすみません‥‥

ただ気になったのでISLeさんのコードでcpu_timerでFPSを測ってみたところ
58.6876[fps/boost]
59.6046[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
59.6046[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
59.6046[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
50.8626[fps/boost]
69.3581[fps/boost]
55.2855[fps/boost]
59.6046[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
57.7984[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
57.7984[fps/boost]
59.6046[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
59.6046[fps/boost]
55.2855[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
56.0985[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
59.6046[fps/boost]
58.6876[fps/boost]
58.6876[fps/boost]
55.2855[fps/boost]
と、かなりばらつきがありました。これは、cpu_timerが悪いのか、GetNowCountを使っているせいなのか、どうなんでしょう‥‥



もしcpu_timerが悪いとしたら59.8FPSになってしまうのもそれが関係してる可能性はありそうですが‥‥
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#13

投稿記事 by ISLe » 13年前

最初の質問のコードですが、誤差が出るのは連続していない部分があるからです。
  • 1フレームずつウェイト時間を求めるので誤差が出る
    →1秒(60フレーム)といったキリの良いところでつじつまが合うようにする
  • ウェイト処理を分けるので誤差が出る
    →1フレーム全体の経過時間で判断する
  • 経過時間を記録した後にタイマーをリセットするので誤差が出る
    →途中でタイマーをリセットせず常に差分を使う
FPS制御に関しては、ウェイト時間を求めてウェイトを入れる、という考え方ではなく、フレームごとに既定の経過時間を超えたかどうか、というふうに考えると安定します。

計算したFPSの値が安定しないのも誤差のせいです。

(追記)
あと1/60は割り切れないので1フレームずつ計算した結果が安定しないというのもあると思います。
最後に編集したユーザー ISLe on 2012年4月26日(木) 02:07 [ 編集 2 回目 ]

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#14

投稿記事 by nullptr » 13年前

なるほど・・・とりあえずここまで来たんで勉強も兼ねて№1のコードを修正してみます。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#15

投稿記事 by nullptr » 13年前

ISLe さんが書きました:
  • 1フレームずつウェイト時間を求めるので誤差が出る
    →1秒(60フレーム)といったキリの良いところでつじつまが合うようにする
  • ウェイト処理を分けるので誤差が出る
    →1フレーム全体の経過時間で判断する
  • 経過時間を記録した後にタイマーをリセットするので誤差が出る
    →途中でタイマーをリセットせず常に差分を使う
すみません。3つ目の点ですが、これってオーバーフローとかしそうな気がするんですがそんなことはないんでしょうか?
それと2つ目の意味がよくわかりません。えっと、ウェイト処理を分けるというのはどういうことでしょうか・・・すみません教えて頂けますでしょうか?
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#16

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:すみません。3つ目の点ですが、これってオーバーフローとかしそうな気がするんですがそんなことはないんでしょうか?
オーバーフローしますよ。
わたしのコードはオーバーフローしてもちゃんと動くように作ってあります。
boost::timer::nanosecond_typeも整数型なのでオーバーフローしても大丈夫なようにできると思います。
新月獅子 さんが書きました:それと2つ目の意味がよくわかりません。えっと、ウェイト処理を分けるというのはどういうことでしょうか・・・すみません教えて頂けますでしょうか?
1つ目がウェイト時間自体が誤差を持つということですが、2つ目はその誤差を持つウェイト時間分待つという処理がさらに誤差を広げるという意味です。
フレームの開始時間とかウェイト処理の開始時間とか基準をたくさん作るとズレが生じるきっかけになります。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#17

投稿記事 by nullptr » 13年前

ISLe さんが書きました:
新月獅子 さんが書きました:すみません。3つ目の点ですが、これってオーバーフローとかしそうな気がするんですがそんなことはないんでしょうか?
オーバーフローしますよ。
わたしのコードはオーバーフローしてもちゃんと動くように作ってあります。
boost::timer::nanosecond_typeも整数型なのでオーバーフローしても大丈夫なようにできると思います。
すみません、どこでオーバーフロー対策しているのかわかりませんでした(汗)
具体的にどうしているのか教えて頂けませんでしょうか
新月獅子 さんが書きました:それと2つ目の意味がよくわかりません。えっと、ウェイト処理を分けるというのはどういうことでしょうか・・・すみません教えて頂けますでしょうか?
1つ目がウェイト時間自体が誤差を持つということですが、2つ目はその誤差を持つウェイト時間分待つという処理がさらに誤差を広げるという意味です。
フレームの開始時間とかウェイト処理の開始時間とか基準をたくさん作るとズレが生じるきっかけになります。
なるほど、そういう意味でしたか。ありがとうございます。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#18

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:すみません、どこでオーバーフロー対策しているのかわかりませんでした(汗)
具体的にどうしているのか教えて頂けませんでしょうか
最新の時刻(GetNowCount())と前回記録した時刻をそのまま比較せずに減算しているだけです。
オーバーフローがあると時刻を比較した結果は定まりませんが差は常に正しく求まります。

32ビットintなので1フレームに25日間程度掛かる負荷があると破綻しますがそれはあり得ないと想定してます。
というかおそらく数分でハングアップとみなされますよね。
スタンバイや休止状態で25日間程度放置されたらマズイですけど、そのあたりはウィンドウの移動とか最小化(非アクティブ状態)とかの対策とまとめてやる部分で公開してるコードには(いまのところ)含まれてません。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#19

投稿記事 by nullptr » 13年前

ISLe さんが書きました:
新月獅子 さんが書きました:すみません、どこでオーバーフロー対策しているのかわかりませんでした(汗)
具体的にどうしているのか教えて頂けませんでしょうか
最新の時刻(GetNowCount())と前回記録した時刻をそのまま比較せずに減算しているだけです。
オーバーフローがあると時刻を比較した結果は定まりませんが差は常に正しく求まります。

32ビットintなので1フレームに25日間程度掛かる負荷があると破綻しますがそれはあり得ないと想定してます。
というかおそらく数分でハングアップとみなされますよね。
スタンバイや休止状態で25日間程度放置されたらマズイですけど、そのあたりはウィンドウの移動とか最小化(非アクティブ状態)とかの対策とまとめてやる部分で公開してるコードには(いまのところ)含まれてません。
ああ、確かにそのまま減算しちゃえばオーバーフローなんて関係ないですね‥‥気づきませんでした、ありがとうございます。

とりあえず2点目と3点目を意識して書きなおしてみました。
boost::timer::nanosecond_type Now;
const float test = 1000.f/Fps*1000000.f;
です。

コード:

		for(i=0;;i++){
			if( Timer.elapsed().wall - Time > test ) break;
			if( ProcessMessage() ) return -1;
		}
		printfDx( "%f[fps/boost]%d   %f[fps/Dx]\n" , 1000.f/((float)((Now=Timer.elapsed().wall) - Time)/1000000.f) , i , 1000000.f/((float)(GetNowHiPerformanceCount())-f) );
		f=(float)(GetNowHiPerformanceCount());
		Time = Now;
FPS制御に関しては、ウェイト時間を求めてウェイトを入れる、という考え方ではなく、フレームごとに既定の経過時間を超えたかどうか、というふうに考えると安定します。
これを参考に、1000.f/Fps*1000000.fを越えるまでは次の処理(フレーム)へ入らない、と判断するようにしてみました。boost::cpu_timerは59.6ばかり吐き出すのでDxライブラリの高精度カウンタでも計測しています。

吐き出し結果は
59.6046[fps/boost]11529 58.3873[fps/DX]
59.6046[fps/boost]13307 61.192[fps/DX]
59.6046[fps/boost]13317 59.4601[fps/DX]
59.6046[fps/boost]11348 59.1191[fps/DX]
59.6046[fps/boost]13332 61.9924[fps/DX]
59.6046[fps/boost]13488 60.9013[fps/DX]
59.6046[fps/boost]13452 61.1471[fps/DX]
59.6046[fps/boost]13432 59.5983[fps/DX]
59.6046[fps/boost]13557 59.7836[fps/DX]
59.6046[fps/boost]13498 60.584[fps/DX]
59.6046[fps/boost]13065 60.4266[fps/DX]
59.6046[fps/boost]11489 56.8925[fps/DX]
52.9819[fps/boost]10707 55.322[fps/DX]
59.6046[fps/boost]11270 64.3211[fps/DX]
59.6046[fps/boost]13164 60.8125[fps/DX]
59.6046[fps/boost]13201 61.2933[fps/DX]
59.6046[fps/boost]13186 59.755[fps/DX]
59.6046[fps/boost]13283 60.2809[fps/DX]
59.6046[fps/boost]13206 60.4412[fps/DX]
59.6046[fps/boost]12802 60.5694[fps/DX]
59.6046[fps/boost]13019 61.024[fps/DX]
59.6046[fps/boost]12848 61.3836[fps/DX]
59.6046[fps/boost]12917 59.9772[fps/DX]
59.6046[fps/boost]12570 60.4449[fps/DX]
59.6046[fps/boost]11896 60.9682[fps/DX]
59.6046[fps/boost]12866 61.3836[fps/DX]
59.6046[fps/boost]12907 59.6908[fps/DX]
59.6046[fps/boost]12969 60.3173[fps/DX]
59.6046[fps/boost]13132 60.6722[fps/DX]
59.6046[fps/boost]13084 61.2107[fps/DX]
59.6046[fps/boost]13015 59.7872[fps/DX]
59.6046[fps/boost]13076 62.2355[fps/DX]
59.6046[fps/boost]13109 60.5767[fps/DX]
59.6046[fps/boost]13221 61.207[fps/DX]
59.6046[fps/boost]13203 59.9628[fps/DX]
59.6046[fps/boost]13216 60.4449[fps/DX]
59.6046[fps/boost]13283 60.8717[fps/DX]
59.6046[fps/boost]13306 61.3309[fps/DX]
59.6046[fps/boost]13294 59.8982[fps/DX]
59.6046[fps/boost]11481 60.1395[fps/DX]
59.6046[fps/boost]12689 59.8767[fps/DX]
59.6046[fps/boost]12917 61.1247[fps/DX]
59.6046[fps/boost]13137 59.6908[fps/DX]
59.6046[fps/boost]13248 60.1468[fps/DX]
59.6046[fps/boost]13432 60.6281[fps/DX]
59.6046[fps/boost]13250 61.024[fps/DX]
59.6046[fps/boost]13239 59.5841[fps/DX]
59.6046[fps/boost]13308 60.0492[fps/DX]
59.6046[fps/boost]13299 60.1287[fps/DX]
59.6046[fps/boost]13092 60.757[fps/DX]
59.6046[fps/boost]13467 61.2482[fps/DX]
59.6046[fps/boost]12629 60.3355[fps/DX]
59.6046[fps/boost]12165 60.8162[fps/DX]
59.6046[fps/boost]11024 62.7746[fps/DX]
59.6046[fps/boost]11791 61.0538[fps/DX]
59.6046[fps/boost]13482 61.8888[fps/DX]
59.6046[fps/boost]13219 59.8337[fps/DX]
59.6046[fps/boost]13164 60.3573[fps/DX]
59.6046[fps/boost]13242 60.8162[fps/DX]
59.6046[fps/boost]13187 61.2445[fps/DX]
59.6046[fps/boost]13279 59.8623[fps/DX]
59.6046[fps/boost]13125 60.2156[fps/DX]
59.6046[fps/boost]13180 60.5804[fps/DX]
59.6046[fps/boost]13271 61.106[fps/DX]
59.6046[fps/boost]13092 59.8193[fps/DX]
59.6046[fps/boost]13251 60.1142[fps/DX]
59.6046[fps/boost]13195 60.7533[fps/DX]
59.6046[fps/boost]13273 60.9793[fps/DX]
59.6046[fps/boost]13248 61.4024[fps/DX]
59.6046[fps/boost]13184 60.0998[fps/DX]
59.6046[fps/boost]12225 60.562[fps/DX]
59.6046[fps/boost]12231 60.7423[fps/DX]
59.6046[fps/boost]12160 60.2591[fps/DX]
59.6046[fps/boost]11449 61.7894[fps/DX]
59.6046[fps/boost]13191 60.6722[fps/DX]
59.6046[fps/boost]12859 61.0463[fps/DX]
59.6046[fps/boost]13217 59.6766[fps/DX]
59.6046[fps/boost]13027 59.641[fps/DX]
59.6046[fps/boost]13060 60.1938[fps/DX]
59.6046[fps/boost]13206 60.7903[fps/DX]
59.6046[fps/boost]13132 61.2445[fps/DX]
59.6046[fps/boost]13193 61.7055[fps/DX]
59.6046[fps/boost]13115 59.8086[fps/DX]
59.6046[fps/boost]13128 60.6686[fps/DX]
59.6046[fps/boost]13056 60.868[fps/DX]
59.6046[fps/boost]12967 61.4251[fps/DX]
59.6046[fps/boost]11898 59.9413[fps/DX]
59.6046[fps/boost]13175 60.5034[fps/DX]
59.6046[fps/boost]13191 60.9385[fps/DX]
59.6046[fps/boost]13321 59.5486[fps/DX]
59.6046[fps/boost]13249 59.8086[fps/DX]
59.6046[fps/boost]13094 60.412[fps/DX]
59.6046[fps/boost]13124 60.8236[fps/DX]
59.6046[fps/boost]13236 61.3121[fps/DX]
59.6046[fps/boost]13112 59.8158[fps/DX]
59.6046[fps/boost]13182 60.27[fps/DX]
59.6046[fps/boost]13209 60.3938[fps/DX]
59.6046[fps/boost]13124 61.1546[fps/DX]
59.6046[fps/boost]13167 59.7229[fps/DX]
59.6046[fps/boost]13222 60.0312[fps/DX]
59.6046[fps/boost]13064 60.4303[fps/DX]
59.6046[fps/boost]11646 60.8643[fps/DX]
59.6046[fps/boost]13110 61.3987[fps/DX]
59.6046[fps/boost]13199 60.0637[fps/DX]
59.6046[fps/boost]13208 60.4193[fps/DX]
59.6046[fps/boost]13330 60.5657[fps/DX]
59.6046[fps/boost]13093 61.3196[fps/DX]
59.6046[fps/boost]13244 59.8444[fps/DX]
59.6046[fps/boost]13256 60.2991[fps/DX]
59.6046[fps/boost]13293 60.7386[fps/DX]
59.6046[fps/boost]13396 61.1845[fps/DX]
59.6046[fps/boost]13079 61.6409[fps/DX]
59.6046[fps/boost]13380 59.9089[fps/DX]
59.6046[fps/boost]12231 62.5313[fps/DX]
59.6046[fps/boost]9714 60.8162[fps/DX]
59.6046[fps/boost]13410 61.192[fps/DX]
59.6046[fps/boost]12951 61.8582[fps/DX]
59.6046[fps/boost]11760 60.1721[fps/DX]
59.6046[fps/boost]13203 60.5437[fps/DX]
59.6046[fps/boost]13009 61.2783[fps/DX]
59.6046[fps/boost]13103 59.8731[fps/DX]
59.6046[fps/boost]12958 62.0117[fps/DX]
59.6046[fps/boost]12959 60.5364[fps/DX]
59.6046[fps/boost]13238 60.831[fps/DX]
59.6046[fps/boost]13230 61.6219[fps/DX]
59.6046[fps/boost]9777 60.1649[fps/DX]
59.6046[fps/boost]12846 60.5437[fps/DX]
59.6046[fps/boost]13295 60.7349[fps/DX]
59.6046[fps/boost]13079 61.3046[fps/DX]
59.6046[fps/boost]13292 59.7051[fps/DX]
59.6046[fps/boost]13083 60.2845[fps/DX]
59.6046[fps/boost]13103 60.6796[fps/DX]
59.6046[fps/boost]8791 61.1995[fps/DX]
59.6046[fps/boost]11744 61.9809[fps/DX]
59.6046[fps/boost]12476 60.0925[fps/DX]
59.6046[fps/boost]12972 60.9385[fps/DX]
59.6046[fps/boost]13199 59.5948[fps/DX]
59.6046[fps/boost]13145 59.8193[fps/DX]
59.6046[fps/boost]13378 60.2991[fps/DX]
59.6046[fps/boost]13242 60.6759[fps/DX]
59.6046[fps/boost]13255 61.1359[fps/DX]
59.6046[fps/boost]13154 61.4968[fps/DX]
59.6046[fps/boost]13042 58.751[fps/DX]
59.6046[fps/boost]12498 64.3376[fps/DX]
59.6046[fps/boost]13135 61.0948[fps/DX]
59.6046[fps/boost]13303 59.6516[fps/DX]
59.6046[fps/boost]13413 59.8695[fps/DX]
59.6046[fps/boost]13235 60.518[fps/DX]
59.6046[fps/boost]10785 60.6355[fps/DX]
59.6046[fps/boost]13146 61.1583[fps/DX]
59.6046[fps/boost]13133 59.7979[fps/DX]
59.6046[fps/boost]13205 60.2119[fps/DX]
59.6046[fps/boost]13111 60.6281[fps/DX]
59.6046[fps/boost]13398 61.1247[fps/DX]
59.6046[fps/boost]13238 59.7229[fps/DX]
59.6046[fps/boost]13258 60.1504[fps/DX]
59.6046[fps/boost]13213 60.5437[fps/DX]
59.6046[fps/boost]13155 60.905[fps/DX]
59.6046[fps/boost]13332 59.5522[fps/DX]
59.6046[fps/boost]13164 59.9089[fps/DX]
59.6046[fps/boost]13270 60.3974[fps/DX]
59.6046[fps/boost]13331 60.8976[fps/DX]
59.6046[fps/boost]13238 60.757[fps/DX]
59.6046[fps/boost]12226 61.7856[fps/DX]
59.6046[fps/boost]12774 60.2192[fps/DX]
59.6046[fps/boost]13240 60.6907[fps/DX]
59.6046[fps/boost]13286 61.1658[fps/DX]
59.6046[fps/boost]13324 59.7051[fps/DX]
59.6046[fps/boost]13175 60.1287[fps/DX]
59.6046[fps/boost]13236 60.573[fps/DX]
59.6046[fps/boost]13329 61.0314[fps/DX]
59.6046[fps/boost]13421 61.4855[fps/DX]
59.6046[fps/boost]13444 60.0601[fps/DX]
59.6046[fps/boost]13402 60.4705[fps/DX]
59.6046[fps/boost]12778 59.4248[fps/DX]
59.6046[fps/boost]10416 61.8429[fps/DX]
59.6046[fps/boost]12826 63.857[fps/DX]
59.6046[fps/boost]13439 60.5767[fps/DX]
59.6046[fps/boost]13484 61.065[fps/DX]
59.6046[fps/boost]12425 59.3824[fps/DX]
59.6046[fps/boost]13432 60.0276[fps/DX]
59.6046[fps/boost]13314 59.9556[fps/DX]
59.6046[fps/boost]13617 60.423[fps/DX]
59.6046[fps/boost]13375 60.868[fps/DX]
59.6046[fps/boost]13294 61.2107[fps/DX]
59.6046[fps/boost]13206 59.8337[fps/DX]
59.6046[fps/boost]13388 60.1649[fps/DX]
59.6046[fps/boost]13528 60.7533[fps/DX]
59.6046[fps/boost]13531 61.4893[fps/DX]
59.6046[fps/boost]13398 59.6125[fps/DX]
59.6046[fps/boost]13136 59.9988[fps/DX]
59.6046[fps/boost]13185 59.8086[fps/DX]
59.6046[fps/boost]12838 61.0054[fps/DX]
59.6046[fps/boost]11368 61.5347[fps/DX]
59.6046[fps/boost]8209 60.1106[fps/DX]
59.6046[fps/boost]13171 60.3901[fps/DX]
59.6046[fps/boost]12773 60.931[fps/DX]
59.6046[fps/boost]13213 59.3718[fps/DX]
59.6046[fps/boost]13198 60.0096[fps/DX]
59.6046[fps/boost]13298 60.4558[fps/DX]
59.6046[fps/boost]13166 60.8606[fps/DX]
59.6046[fps/boost]13118 61.297[fps/DX]
59.6046[fps/boost]13258 59.9736[fps/DX]
59.6046[fps/boost]13222 59.9772[fps/DX]
59.6046[fps/boost]13229 60.7977[fps/DX]
59.6046[fps/boost]13345 61.222[fps/DX]
59.6046[fps/boost]13537 59.8229[fps/DX]
59.6046[fps/boost]13560 60.2736[fps/DX]
59.6046[fps/boost]13534 60.7349[fps/DX]
59.6046[fps/boost]13547 61.1284[fps/DX]
59.6046[fps/boost]12756 59.4636[fps/DX]
59.6046[fps/boost]12748 59.6445[fps/DX]
59.6046[fps/boost]10777 60.5987[fps/DX]
59.6046[fps/boost]13188 61.1172[fps/DX]
59.6046[fps/boost]13170 61.6447[fps/DX]
59.6046[fps/boost]13547 60.2373[fps/DX]
59.6046[fps/boost]13500 60.7054[fps/DX]
59.6046[fps/boost]13547 61.2107[fps/DX]
59.6046[fps/boost]13568 59.1296[fps/DX]
59.6046[fps/boost]13419 61.7513[fps/DX]
59.6046[fps/boost]13199 59.8946[fps/DX]
59.6046[fps/boost]13107 62.3131[fps/DX]
59.6046[fps/boost]13339 60.9347[fps/DX]
59.6046[fps/boost]13331 61.459[fps/DX]
59.6046[fps/boost]13263 61.5082[fps/DX]
59.6046[fps/boost]13162 60.2156[fps/DX]
59.6046[fps/boost]11874 60.5547[fps/DX]
59.6046[fps/boost]13343 61.2145[fps/DX]
59.6046[fps/boost]13398 59.8015[fps/DX]
59.6046[fps/boost]13451 60.1902[fps/DX]
59.6046[fps/boost]13189 60.6722[fps/DX]
59.6046[fps/boost]13134 61.267[fps/DX]
59.6046[fps/boost]13365 59.6588[fps/DX]
59.6046[fps/boost]13460 60.2156[fps/DX]
59.6046[fps/boost]13572 60.8347[fps/DX]
59.6046[fps/boost]13251 59.7443[fps/DX]
59.6046[fps/boost]12370 62.1234[fps/DX]
59.6046[fps/boost]12791 61.8276[fps/DX]
59.6046[fps/boost]13316 60.31[fps/DX]
59.6046[fps/boost]13348 60.9496[fps/DX]
59.6046[fps/boost]13402 61.3271[fps/DX]
59.6046[fps/boost]11416 61.0352[fps/DX]
59.6046[fps/boost]13321 61.6067[fps/DX]
59.6046[fps/boost]13055 60.4668[fps/DX]
59.6046[fps/boost]13375 60.9273[fps/DX]
59.6046[fps/boost]13296 61.2895[fps/DX]
59.6046[fps/boost]13464 60.1395[fps/DX]
59.6046[fps/boost]13436 60.746[fps/DX]
59.6046[fps/boost]13630 61.3121[fps/DX]
59.6046[fps/boost]13458 60.1178[fps/DX]
59.6046[fps/boost]13670 60.573[fps/DX]
59.6046[fps/boost]13483 61.0054[fps/DX]
59.6046[fps/boost]13623 59.1366[fps/DX]
59.6046[fps/boost]12260 61.459[fps/DX]
59.6046[fps/boost]11634 59.7943[fps/DX]
59.6046[fps/boost]12904 60.3209[fps/DX]
59.6046[fps/boost]13011 60.5694[fps/DX]
59.6046[fps/boost]12868 60.9199[fps/DX]
59.6046[fps/boost]13293 62.1659[fps/DX]
59.6046[fps/boost]13542 60.7128[fps/DX]
59.6046[fps/boost]13670 60.8939[fps/DX]
59.6046[fps/boost]13497 61.3346[fps/DX]
59.6046[fps/boost]13589 59.8767[fps/DX]
59.6046[fps/boost]13589 60.3427[fps/DX]
59.6046[fps/boost]13512 60.7533[fps/DX]
59.6046[fps/boost]13546 60.9088[fps/DX]
59.6046[fps/boost]13501 61.6637[fps/DX]
59.6046[fps/boost]13573 60.2156[fps/DX]
59.6046[fps/boost]13586 60.6318[fps/DX]
59.6046[fps/boost]13533 61.0612[fps/DX]
59.6046[fps/boost]13588 59.6623[fps/DX]
59.6046[fps/boost]13522 60.0565[fps/DX]
でした。

やはり前述のようにcpu_timerは59.6しか吐きません。(パソコンの状態によっては№1と同じように59.8)。
一方Dxライブラリの方はばらつきはありますが、平均的に見ると60~61あたりのようです。

これらを改善するとしたら残る№1だと思うんですが、
ISLe さんが書きました:
  • 1フレームずつウェイト時間を求めるので誤差が出る
    →1秒(60フレーム)といったキリの良いところでつじつまが合うようにする
もう1フレームずつウェイトを求めているわけではありませんのですが、キリの良いところでつじつまが合うようにするということはキリの良くない59フレームは大雑把で60フレーム目だけ1秒に細かく調節すれば良いという解釈でよいのでしょうか?

質問責めですみません。よろしくおねがいします。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#20

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:const float test = 1000.f/Fps*1000000.f;
このtestを60(Fps)回足したものを表示してみてください。

GetNowHiPerformanceCountのほうは2回呼び出している間の誤差です。
大ざっぱに言うとprintfDxに掛かっている処理時間による誤差ですかね。
新月獅子 さんが書きました:もう1フレームずつウェイトを求めているわけではありませんのですが、キリの良いところでつじつまが合うようにするということはキリの良くない59フレームは大雑把で60フレーム目だけ1秒に細かく調節すれば良いという解釈でよいのでしょうか?
つじつまを合わせるというのは、60FPSなら60フレーム分の経過時間をすべて足したときにぴったり1秒になるように均すということです。
もちろんしわ寄せがどこかに集中するような均し方ではいけません。

例えば1ミリ秒単位で
1フレーム目から2フレーム目に切り替わる時刻は1000*1/60ミリ秒後です。
2フレーム目から3フレーム目に切り替わる時刻は1000*2/60ミリ秒後です。
以下同様とすると
60フレーム目から61フレーム目に切り替わるのは1000*60/60ミリ秒後です。
1000*60/60は間違いなく1000になります。ぴったり1秒後です。

以上からnフレーム目に掛かる時間は(1000*n/60 - 1000*(n-1)/60)となります。
整数で計算すると1~60フレーム目の間に16ミリ秒と17ミリ秒のフレームが適当に現れます。
ぴったり1秒経過したところで基準を1秒ずらして再び1フレーム目から数えます。

大事なのは、すべてのフレームが1000*1/60になることは絶対に無いということです。

ウチで公開してるコードに以下のコードがあります。
#60FPSではvsync_unitmsが1000、vsync_framesが60です。

コード:

			int disttime = ((frame_count + 1) * vsync_unitms / vsync_frames) - frame_ticktime;
			frame_count = (frame_count + 1) % vsync_frames;
			frame_ticktime = frame_count == 0 ? 0 : frame_ticktime + disttime;
disttimeが上記の考え方を元に求めている個々のフレームに掛けるべき時間です。

それから浮動小数点数を使うとぴったり1秒にするのは極めて難しくなります。
誤差が付き物ですから。
1フレームあたりの誤差を最小にしようということなのでしょうけど時間が経つほどにズレていきます。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#21

投稿記事 by nullptr » 13年前

ISLe さんが書きました:
新月獅子 さんが書きました:const float test = 1000.f/Fps*1000000.f;
このtestを60(Fps)回足したものを表示してみてください。

GetNowHiPerformanceCountのほうは2回呼び出している間の誤差です。
大ざっぱに言うとprintfDxに掛かっている処理時間による誤差ですかね。
新月獅子 さんが書きました:もう1フレームずつウェイトを求めているわけではありませんのですが、キリの良いところでつじつまが合うようにするということはキリの良くない59フレームは大雑把で60フレーム目だけ1秒に細かく調節すれば良いという解釈でよいのでしょうか?
つじつまを合わせるというのは、60FPSなら60フレーム分の経過時間をすべて足したときにぴったり1秒になるように均すということです。
もちろんしわ寄せがどこかに集中するような均し方ではいけません。

例えば1ミリ秒単位で
1フレーム目から2フレーム目に切り替わる時刻は1000*1/60ミリ秒後です。
2フレーム目から3フレーム目に切り替わる時刻は1000*2/60ミリ秒後です。
以下同様とすると
60フレーム目から61フレーム目に切り替わるのは1000*60/60ミリ秒後です。
1000*60/60は間違いなく1000になります。ぴったり1秒後です。

以上からnフレーム目に掛かる時間は(1000*n/60 - 1000*(n-1)/60)となります。
整数で計算すると1~60フレーム目の間に16ミリ秒と17ミリ秒のフレームが適当に現れます。
ぴったり1秒経過したところで基準を1秒ずらして再び1フレーム目から数えます。

大事なのは、すべてのフレームが1000*1/60になることは絶対に無いということです。

ウチで公開してるコードに以下のコードがあります。
#60FPSではvsync_unitmsが1000、vsync_framesが60です。

コード:

			int disttime = ((frame_count + 1) * vsync_unitms / vsync_frames) - frame_ticktime;
			frame_count = (frame_count + 1) % vsync_frames;
			frame_ticktime = frame_count == 0 ? 0 : frame_ticktime + disttime;
disttimeが上記の考え方を元に求めている個々のフレームに掛けるべき時間です。

それから浮動小数点数を使うとぴったり1秒にするのは極めて難しくなります。
誤差が付き物ですから。
1フレームあたりの誤差を最小にしようということなのでしょうけど時間が経つほどにズレていきます。
ありがとうございます。
浮動小数点数を使うと誤差が出てしまいますか・・・でもそれは整数を使っても同じでは無いのでしょうか?
大事なのは、すべてのフレームが1000*1/60になることは絶対に無いということです。
なるほど、全フレームをきっちりかっちり揃えようとしても無駄ということですか。
ISLeさんのコードをよく読みなおしてまた修正してみることにします。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: FPSがうまく制御できない

#22

投稿記事 by ISLe » 13年前

新月獅子 さんが書きました:浮動小数点数を使うと誤差が出てしまいますか・・・でもそれは整数を使っても同じでは無いのでしょうか?
最初からそういうつもりでわたしの文章を読んでいるから理解できないのではないですか?

60FPSで60フレーム目から61フレーム目に切り替わるのは1000*60/60ミリ秒後ですと書きましたよ。
1000/60*60ではないですよ。
1000*60/60です。
違いが分かりますか?
新月獅子 さんが書きました:なるほど、全フレームをきっちりかっちり揃えようとしても無駄ということですか。
全フレームを統一することは絶対にできないのですよ。
割り切れないのですから。
1フレームずつ理想の値に近付けるようにする必要があります。
新月獅子 さんが書きました:ISLeさんのコードをよく読みなおしてまた修正してみることにします。
計算式中のオペランドの順番にも意味があります。
文字通り一文字も漏らさず意味を考えてみてください。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: FPSがうまく制御できない

#23

投稿記事 by nullptr » 13年前

ISLeさんご返答有り難うございます。
60FPSで60フレーム目から61フレーム目に切り替わるのは1000*60/60ミリ秒後ですと書きましたよ。
1000/60*60ではないですよ。
1000*60/60です。
違いが分かりますか?
しっかりと文章を読まず本当に申し訳ありませんでした。
ご指摘のように1000*60/60で計算するようにし、今まではwallを浮動小数点数に直してましたが逆に他のものを__int64に直し浮動小数点数での計算をなくし、
FPSの計測は1秒ごと(60フレームごと)に計算するようにしたところ、ほぼ60FPSで一定になるようになりました。

長々と聞いてくる私に丁寧にご回答下さり本当にありがとうございました。解決とさせて頂きます。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

閉鎖

“C言語何でも質問掲示板” へ戻る