質問です。
環境:Win2000,VC++6.0,MFCです。
Virtualallocである領域を確保します。
確保した領域に一定のタイミングで決まった量のデータが入ります。
入ってきたデータを確保した領域の後ろ?のほうに退避させたいです。
退避させる理由は、ある一定のタイミングでデータが入ってくるので入っていたデータ
は問答無用で消されてしまいます。
入ってくるデータをとめることは出来ません。
Virtualallocで確保したメモリ内のデータの移動(退避)方法を教えてください。
よろしくお願いします。
移動したいタイミングで、メモリをコピーして下さい。
今の情報で分かるのはこれくらいです。
ワザワザVirtualAllocする理由は?
普通のmallocで耐えられるなら、そちらの方が良いと思う。
メモリ割当てアルゴリズムを自分で実装するのはよっぽどのことですよ!
少なくとも以下のことがわからなければ、判断できません。
・データのサイズ
・データの流入間隔
・データ処理時間
・そのデータの処理
アルゴリズム自体はMSDNにも載ってた気がする。
アルゴリズムは↓のような物がある。名前自体はうろ覚え・・・ゴメン
・ファーストフィット
・ジャストフィット
・その他・・・
ようは、空き領域の探し方と判定法が違う。
こういった場合、サイクリックファイルにすれば問題ないはずですが。
書き込み側のソフトは変更できないの?
新しいデータが後ろに入るのでよければ…
最初に VirtualAlloc でデカい領域を予約だけしておいて
実際にデータが入ってきた段階で、後ろの方をアドレス指定してコミットするとか。
返答ありがとうございます。
入ってくるデータは画像でサイズは300Mバイト程度になります。
結構でかいです。
データの流入間隔は...ごめんなさい。今ちょっと分かりません。調べてきます。
データ処理時間、そのデータの処理はこれから実装するのでまだ不明です。
データの取り込みに間に合うような処理をしなくてはならないので
出来るだけデータのコピーに時間を掛けられません。
実は、書き込み側のソフトは変更できるので上記の流入間隔はいかようにでも
変更できるんですが可能な限り早くと言われているので書き込み側のソフトは変更なし
の方向で...。
僕が考えているのは以下の方法です。
Virtualallocで元画像の2倍と余裕をみて+αのサイズの領域確保します。
確保した領域の先頭から画像が入ってくるので、その入ってきた画像の末端から
ちょいとオフセットしたところに入ったデータをそのままコピーする。
で、コピー先で処理をするって方法です。
画像のサイズは固定で可変しません。
ファーストフィット、ジャストフィット、サイクリックファイル調べてみます。
> データ処理時間、そのデータの処理はこれから実装するのでまだ不明です。
> データの取り込みに間に合うような処理をしなくてはならないので
間に合うならば、コピーの必要が無いように思います。
しかし、一番気になるのは、「べし」さんが、VirtualAllocを選択した理由です。
色々考えているように見受けられるのですが、、
正直、「べし」さんのスキルを測りかねてます。
仮想メモリ空間と物理メモリ空間を明確に認識していて、
旨くそのリンクを化かしてやろうとしているならば、それは無理です。
理由は、物理メモリは基本的にCPU閉じた話であり、
CPU内部キャッシュ絡みに縛られています。
仮想空間中の領域コピーに関して、性能的に有利な方法はありません。
(通常のポインタと同様に扱ってください)
通常、固定領域をmallocしておく方法で問題はありません。
ただし、仮想メモリ空間を明示的に管理したかったり、
COMIT等を明示的に行って、ワーキングセットを管理しようとしているならば
突っ込む必要はないでしょう。
>入ってくるデータは画像でサイズは300Mバイト程度になります。
>結構でかいです。
ファイルが大きすぎます。
変なこと考えないで、ファイルに保存することをお薦めします。
>出来るだけデータのコピーに時間を掛けられません。
>実は、書き込み側のソフトは変更できるので上記の流入間隔はいかようにでも
これらのことから考えると、始めからメモリorファイル(約300Mバイト)を2面持っておい
て、
書き込む側でも処理する側でも、交互に処理すればよいのではないですか?
サイズが300Mもあるんでしたら素直にファイルに落としたほうが
安全だと思いますけれどねぇ。
ファイル保存にかかる時間が心配ならREEさんの案も拝借して
バッファを二つ用意しておいて交互に使用するようにして
データが載った方をファイルに落とす仕組みを作っておくのがよいと
思います。
Bosscatさんが言われているように書き込まれている内容だけで考えると
わざわざVirtualAllocを使う理由がわかりません。
単なるバッファなら普通にGlobalAlloc使っても大差は無いと思います。
もしかしてデータ引渡し上の条件にあるのかなぁ。
VirtualAllocで確保したものを引き渡し場所に用意しろとか。
画像データに加工をしたいのであれば、ファイルから読み出して
やれば、取り込みタイミングを気にする必要はありませんしね。
加工側は別スレッドにしても良いだろうし、別プロセスでも良いかも
しれませんね。
オンメモリで処理しなければいけない理由とか設計上の制約の話が
説明されていないので方法的には確実な線という事で。
VirtualAlloc() を用いる事にしたわけが書いていないのでなんとも判断がつかないのですが
仮想記憶ということに付いてあまりお分かりでないのか、十分な知識があっての上での決定
なのかで書き方も違ってくるのでその辺りが知りたいですね
データーが入ってくるという書き方も気になります。ビデオのように動画を意識しているのか
なにかのハードウエアーがあって、デバイスドライバーが特定の領域に転送するのか
転送の主体が窺い知れるようなことはさっぱり書いていません
仕事の上で秘守契約か何かで書けない事でもあるのでしょうか。それならそうと書いてくれれば
いいのですが、なんだかすっきりません
数ギガバイトのメモリーが積めるご時世なので300MBがでかすぎるとも思いませんが
実メモリーが少なければ、どのように確保しようとも物理メモリー上に存在することを
強制することはた易いことではありません(どこかにしわ寄せが来るという意味です)
しかもどのように VirtualAlloc() を使うつもりなのかも書いていないのでますます
返答が困難です。AWE(アドレスウインドウ化エクステンションというらしい)を利用して
物理空間を扱いたいということなのでしょうか
メモリーが有り余るほど積んでいる環境ならいい手かもしれません(私は薦めませんが)
リングバッファ
「出来るだけ早く!」という要求なのですから
VirtualAllocでメモリをコミットしておくのはよい方法だと思います。
で
なるべく早くコピーせいという要求でしょ
さっさとmemcpyするのが一番早い。
早く!という要求の回答に、なんでファイルを使えなどという
言葉がでてくるのか理解に苦しみますな。
>早く!という要求の回答に、なんでファイルを使えなどという
>言葉がでてくるのか理解に苦しみますな。
経験上のことです。
環境(ハード)は書いてないし、仕様は不明確、このため想像するしかないのですが、
「300MBのデータをn個操作する。」
こう書かれただけで、現状の標準的なハードでは、ファイルを使わざるをえないと考える
のは普通だと思いますが。
実際に、メモリが512MBしかない環境で、300MBのデータを2個以上管理しよう
とすれば、スワップが発生してファイル操作するよりかえって遅くなると思いますが。
技術的な話で盛り上がるのもよいとは思うのですが、現実的なフォローも必要なのでは
ないでしょうか。
Win32 では、malloc() でも GlobalAlloc() でも HeapAlloc() でも最後には
VirtualAlloc() に辿り着くので、その意味で VirtualAlloc() が他の手段より優れて
いるということが理解できません。それに、どの道仮想記憶なのだから、どのように確保
してもその領域を物理記憶上に貼り付けておくことは(AWE を除いては)保証が無いから
(十分な主記憶が積んであれば別ですが)memcpy() がファイルより速いというのは
どの程度の違いを指してのことなのか判りかねます。確かに、ファイルはOSが絡むが
memcpy() は API でさえないのでその分早そうに思えますが、例えば、300MBの領域が
全て常に物理記憶上に存在することが保証できなければ結局ページファイルと主記憶との
交換(ページイン、ページアウト)が発生するので、ファイルに出力するより速いという
主張はあまり説得力がありません