- ベストアンサー
仮想メモリの制御
VC++を使って、 2次配列[1000][640×480]を(FPS30) リングバッファで書き込み、書き出しし、 ディスプレイに出力したいのですが、 当然メモリが足りず、仮想メモリを使用し、さらにFPS30 を大幅に下回ってしまいます。 配列のサイズを小さくすることも可能ですが、 なるべく上記の条件に近い方が望ましいです。 そこで書き込みしたての値を一時あえて仮想メモリに 保存し、必要になる手前で引き出して物理メモリ上に 置いておくといったプログラムを書いてみようかと思うのですが、 実現可能でしょうか? もしくはよりよい対策あればお教えいただけますでしょうか? 当方、知識不足で仮想メモリを制御できるのかどうかも把握しておりません。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
★アドバイス ・メモリマップドファイルをつかってみてはどうですか? これは仮想メモリと同じ仕組みを簡単に実現できる『技』です。 下の『参考URL』やネット検索して下さい。 ・以上。 参考URL: ・http://homepage2.nifty.com/DSS/PT/HTML/Win/FileMapping.htm ・http://marupeke296.com/DXCLS_MemoryMappedFile.html
その他の回答 (6)
- tlieta
- ベストアンサー率14% (1/7)
WEBカメラからの出力ということですが、でしたらわざわざDIBにしなくても動画再生という手法が一番楽だと思います。 また、この処理をするならばDirectX等のグラフィックメモリを用いることも考えられます。 別の方法では、いわゆるストリーミングですね。たとえば、常に60フレームをメモリに溜め込む方法です。使用済みのフレームはメモリから破棄し、現在から60枚先のフレームを取得。この方法ならばAPIだけでも60fpsは出せます。他にもゲームプログラムを参考にすると色々方法は出てくるでしょう。
- zwi
- ベストアンサー率56% (730/1282)
HDDなどではなく、これなどを使えば解決しません? http://www.links.co.jp/html/press2/news_i-ram.html 普通のHDDも間に合いそうな気がするんですけどね。 当然バッファの書き出しはスレッドで行います。
- rinkun
- ベストアンサー率44% (706/1571)
640x480フルカラー(32bit)をFPS30だと35.2MB/sくらいでしょ。速いHDDだったら十分に追いつける速度だと思いますけど。 1000フレームだと30秒くらいでしょうか、適当な動画フォーマットでファイルに吐き出して動画再生プログラムに表示を任せるだけで良いのでは。 # 可逆圧縮系のフォーマットを選べば劣化もないでしょう 自前で表示するにしても、1GBもの配列を取ろうとするとシステムに無用な負担を掛けて反って遅くなるから、数フレーム分だけバッファを持ってファイルから読み込みつつ表示をしていけば十分なのではないですか。
- MrBan
- ベストアンサー率53% (331/615)
# 昨今のWindows上で動くアプリ書いてる時点で、物理的に # どこにあるかを問わず常に仮想メモリ上だと思いますが。 > 実現可能でしょうか? おそらく「実現可能でしょうか?」と質問するような人間が やるよりはもう少し効率的に、既にOSがやってくれてます。 近しいことはできなくはありませんが、おそらく効果は薄い(多分無駄)です。 そもそも、仮想メモリでスワップアウトするような環境で、 物理メモリのロックをかけようとしても失敗して動作できません。 # 仮想メモリなら要求が空きサイズ以上でも受け入れてくれますが、 # 既に物理メモリに入りきらずにスワップされる状況で # そのサイズを確実に取ろうとしてもOSに「無理」と言われて終了です。 > もしくはよりよい対策あればお教えいただけますでしょうか? 1. 他の方のいうように、仮に1pixelに24bit当てても1GBいかないので、メモリを増やしてみる。 また、本気で物理メモリをとりに行くなら、配列は連続した アドレス空間を要求するため、アプリに2GBしかないアドレス 空間も考慮しないと、一見空きがあるように見えても確保失敗します。 # 1GB以上の連続空間ってのは結構難しいはず。 2.ちゃんとボトルネックを探す。本当にメモリのスワップアウトのせいですか? どうやって確認しましたか? 多分、問題の根底は「とにかくメモリ上でぶん回せは早い」という発想と、 アルゴリズム上の無駄にあるのではないでしょうか。 この手の描画だと、システムメモリとグラフィックメモリの間の転送や、 ロック処理などに多大な時間を割かれます。 たとえば1pixel単位で書き出すなど、制御を頻発させたらアウトと思っていいかと。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >当方、知識不足で仮想メモリを制御できるのかどうかも把握しておりません。 ↑ 仮想メモリの制御は OS のお仕事です。 ご自分での制御は難しいです。 >2次配列[1000][640×480]を(FPS30) ↑ 普通にメモリを確保すれば約 293 MBです。 物理メモリが少なくても OS が勝手にディスク・ファイルにスワップ・アウトして 必要になったらスワップ・インします。つまり OS が仮想メモリを制御しているので 物理メモリが足りない環境でも動かせます。でも低速になりますが…。 今回は OS が仮想メモリを管理してもご自分で制御しても無意味です。1秒間に30回でしょ。無理。 ・問題はなぜ FPS30 で2次配列[1000][640×480] ものデータを書き換える必要があるのかです。 前も同じような質問していましたよね。 一体何を行うために 2次配列[1000][640×480] が必要なのでしょうか? 前はグラフを書くのが遅いとかで質問していた方ですよね。 もっと良いアルゴリズムを探した方が良いです。 ・補足要求します。 最終的には何をどのようにしたいのですか? それによりもっと良い方法が見つかるかもしれません。 ・本当に FPS30 で 1000 回も 640×480ドットの画面情報を収集しないといけないのですか?
- Tasuke22
- ベストアンサー率33% (1799/5383)
仮想メモリは1アプリケーションで制御出来る性質のものでは ありません。システム全体で効率を考慮して制御されています。 もっともシステム要求を出せば制御出来るかもしれませんが、 論理ページが現在メモリか仮想メモリかを常にチェックしながら 処理する必要があるので、スーパーバイザーモードで走る必要 があり、これはもうアプリケーションの域を超えていますね。 簡単に効率を上げるのであれば、データベース化が1案です。 データベースは入出力とメモリのバランスを考慮しています。 それ以外であれば、大きな配列は諦めて、自分でファイルに 入出力ですね。仮想メモリの制御より現実的で制御も容易で しょう。 一番簡単なのは4バイトデータなら1.2GB程度のデータなので 今時のPCにしたら2GBくらいの実メモリは容易でしょう。 PCを代えることですね。
補足
ご回答ありがとうございます。 プログラムの内容はFPS30で640×480(320×240でもいいのですが)で WEBカメラから一定時間毎に動画を一時保管し、あるタイミングで 瞬時に放出するものです。 真に申し訳ないのですが、目的、全体の構造は申し上げることができないのですが、反応に瞬発力を要するため、HDに保管してしまうと 目的の処理速度を達成できません。 尚ほかの方も申すとおり配列のサイズは1GBを超えないのですが、 動画出力の際に簡単に使用メモリが1.5GB(2GBのPC)になってしまいます。 フレームバッファに1コマの情報が全てきてから出力するように 指示しているのですが、ここでの処理に時間がかかっております。 フレームレートを優先すると動画が乱れまくります(当然ですが) 巨大な配列を1つ宣言しているものの、他の処理は1コマ分ずつしか 処理していないにもかかわらず、メモリが制限いっぱいにすぐに 到達してしまうのはなぜなのでしょうか?