• ベストアンサー

フレーム待ちの処理速度に関して

2次配列[1000][画素数]を宣言して、1から1000まで順々にフレームレート30でフレームバッファに格納し、再生したいのですが、 格納するのに時間がかかってしまい、コマ落ちせずに再生しようとすると、 1/6くらいの速度になってしまいます。 この場合、例えば、処理速度を速める配列のアドレスの 設定方法等のプログラム上の解決策はありますでしょうか? もしくはビデオカードのマウント等のハード上の 対策しかないのでしょうか? 質問内容に不足があればご指摘ください。 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.3

もし,再生開始していくらか時間が経ってからコマ落ちするようなら, 配列が巨大すぎるのが問題かも. 動画なので仮に 640×480×24bit 程度と仮定すると,1フレーム≒0.88MB, 配列全体では 880MB にもなるので,これだけ巨大になると全体を同時に 実メモリ上に置くわけに行かないからページングが発生するはず. 今回の使用法だと,(少なくともフレーム単位で見れば) 配列の先頭から シーケンシャルに書き込み/読み出しを行うはずだけど,配列の後ろの 方でそれをやる頃には,配列の先頭の方の内容を (もう不要になっているのに) ディスクにページアウトするために遅くなるんじゃないかと思います. ページングが発生しない程度の大きさの配列にして,リングバッファ的に 使う方が速くなると思います.やったことがないのでどれぐらいのサイズが 妥当かはわかりませんが,たぶん数十 MB 以内かな.PC の利用状況にもよる のでユーザが設定できるようにした方がいいと思います. 次に,配列はフレーム単位ではシーケンシャルにアクセスされるはずなので その点はいいけど,1フレーム分の画素が配列内でどういう順番になっている のか質問文からはわかりません. たぶん配列要素の順番が array[フレーム番号][y][x][RGB] と同等の順序に なっていればシーケンシャルアクセスで済むので一番速いはず. (シーケンシャルアクセスで速く変化する添字ほど右側になるようにする.) この順番が違っていると,フレーム内がランダムアクセスになってしまうので キャッシュの効きが悪い (というよりキャッシュライン単位で読むためむしろ 逆効果でキャッシュがない場合よりも遅くなる) と思います. より高速な画像の表示法 http://okwave.jp/qa3010206.html ⇒ 回答 #12 ⇒ 回答 #8 への補足 最後に,多次元配列をシーケンシャルアクセスする場合は,添字ではなくポイ ンタをインクリメントしながらアクセスする方が多少速くなると思います. (多次元になるほど,添字から要素のアドレスを計算する手間がかかるため.)

rairarai
質問者

補足

ありがとうございます。 おっしゃる通り、仮想メモリを使用していたためのタイムラグでした。 説明不足しておりましたが、初めの配列もループして使用するため、 すでにリングバッファにしてあります。 そのためしばらく使用しない配列を故意に一時的にHDに 保管すればよいのかと思っております。 (HDの処理速度がどのくらいかまだ調べておりませんが) また当方、仮想メモリのなんぞやすら今回知ったくらいの知識でして、 故意に一時的にHDに保存するとしたら、仮想メモリを使用する ほうが、ファイルの書き出し、読み込みより早いのでしょうか? むしろ仮想メモリというのは指定して使用するなどの制御は 可能なのでしょうか?

その他の回答 (2)

回答No.2

No.1の回答者です。 DirectXをすでに使用しているのであれば、どの程度の大きさのものをどうやって描画しているのか分からないので、なんとも言えませんが、言われるように、 >描画部分のプログラムの再検討 が、可能性があると思います。 DirectXを使用して適切に処理すれば、よほど昔のPCを使用しているのでなければ、秒間30フレームは難しいことでは無いと思うので、あとは、メモリ操作・描画以外で処理時間がかかっている部分が無いかを確認してみるくらいでしょうか。

回答No.1

一般的にはメモリアクセスは書き込みよりも読み込みのほうが高速で、ランダムアクセスよりもシーケンシャルアクセスの方が高速です。 ですが、画素数を1024x1900として各ピクセルに4バイト使用したとしても、1024x1900x4 = 約7MByteで、少し昔のPCのメモリの転送能力が数百MByte/Sec程度(最近のPCでは1GB/s~10GB/s)ですので、配列へのWrite/Readのみであれば秒間フレーム30はクリアできてると思われます。 ですので、その後の描画処理部分での処理時間の方が比重は大きいはずです。おそらく、先述のread・シーケンシャルアクセス優先を行って高速化で出来たとしても、6倍の高速化は難しいと思います。 描画部分の高速化では、もし今GDIを使用して描画しているのであればDirectXを使用することで高速化できる可能性があります。

rairarai
質問者

補足

ありがとうございます。 シーケンシャルアクセス調べてみましたが、 なかなか難しそうですね。 素人にもわかる文献ご存知の方いらしたら教えてください。 描画部分ではDirectXを使用しておりますので、 あとは描画部分のプログラムの再検討、もしくはハードのスペックアップ が妥当なのでしょうか?