> Win32 では、malloc() でも GlobalAlloc() でも HeapAlloc() でも最後には
> VirtualAlloc() に辿り着くので、<略>
私の知りうる限り(1年前です)Windows2000Proにおいてその様な動作はしないハズです。
HeapAlloc()の先はシステムコールとなっていました。
(new malloc() 達はHeapAlloc()に落ちていきます、VirtualAlloc()もシステムコールに
落ちていきます。)
ページフォルトの抑止に関して:
最近、ここの掲示板に書いたと思いますが、、
これらの抑止はVirtualAlloc()及びVirtualLock()によって制御可能です。
なので、性能計算の条件はオンメモリ上として算出可能です。
もちろん、普通の環境では、他のアプリケーションも有り、
ページフォルトの抑止がパフォーマンスに好影響を与えるとは限りません(ほとんど逆)。
しかし、開発環境によってはそれが許される場合があります。
ヨタ話:
極端な話、ワーキングセット自体を管理下に置くならば
ページフォルトを起こす場合にも、その時間を計算し切ることが可能です。
(極々一部の組み込み系の仕事を除いてメリットはありませんが、、、)
私自身、ワーキングセット自体を意識しての作業となると、
(既存システムの)速度計算ならやったことはありますが、設計したことはありませ
ん。。。
>実際に、メモリが512MBしかない環境で、300MBのデータを2個以上管理しよ
>うとすれば・・・
最初からVirtualallocの使用が前提の質問だよね・・・
300MBのデータの倍を確保するって言ってますしね。
メモリが512MB のPC?
300MB×2=600MB
Virtualallocは物理メモリの予約と確保を行う関数です。
確保できないじゃん。
ん~なPC 使用想定外じゃないの?
>Virtualallocは物理メモリの予約と確保を行う関数です
Virtual って「仮想」ではなく「物理」だったんでしたか!
私は「物理」記憶は Physical だと信じていましたが改宗しなければならないようですね
>ん~なPC 使用想定外じゃないの?
その”想定”についてどこにも何も触れていないのだから、私はそのような仮定はしません
>>Virtualallocは物理メモリの予約と確保を行う関数です
>Virtual って「仮想」ではなく「物理」だったんでしたか!
>私は「物理」記憶は Physical だと信じていましたが改宗しなければならないよう
>ですね
VirtualAllocでメモリをコミットするとは
プロセスの仮想空間に物理メモリを割り当てると意味したと思うのだけど?
MSDNを読んで実際にコードかいてますか?
あ 島さんごめんね
もしPhysicalAllocとか物理メモリを予約して使える関数が
別にあるなら私の勉強不足です。
おしえてくださいね。
>VirtualAllocでメモリをコミットするとは
>プロセスの仮想空間に物理メモリを割り当てると意味したと思うのだけど?
面倒なので MSDN の日本語のページから引用します
<ここから>
メモリ内またはディスクのページングファイル内に、指定されたページ領域に相当する
物理的な記憶域を割り当てます
<ここまで>
のことを指しているのだとしたら、仮想空間に実際の物理領域が対応するということを指して
いると私は読みます。これは MEM_COMMIT と MEM_RESERVE との違いについて書いていると
読みました(予約したら、参加(参与、確定?)できます)
MEM_RESERVE は番地を予約するだけなので MEM_COMMIT で実際に取るまでは仮想記憶を
操作しないから自由度が高いと彼ら(MS)は言っているのですね、欲しいときと、使いたいとき
とが違うことがあるので、そのように使えますよということでしょう
あくまで仮想記憶空間の話だと思いますが(記憶域であって、物理(実)番地が割り当る
わけではないのでそう判断します。仮想空間の番地は物理空間の番地とは別物ですから)、
”またはディスクのページングファイル内に、”があるのですから。
もっとも、物理記憶をページファイルも含めて解釈なさっているのなら別です。
#物理記憶(空間/番地)は仮想記憶(空間/番地)と対比させて使うものだと思いますけど
#違うのかな
>MSDNを読んで実際にコードかいてますか?
いつも MSDN は読むわけではなく、判らないことが出たときには MSDN で調べます
今回も間違ってはいけないと思い、英語の方も日本語の方も WEB 版で調べてから投稿しました
よ
実際にコード書いてるかという質問ですがこれは VirtualAlloc() 使ったことあるか
という意味なんでしょうか?
それとも口先ばかりでコード書けない(書かない)ひよこちゃんは黙ってなさいといいたいので
しょうか?
>もしPhysicalAllocとか物理メモリを予約して使える関数が
>別にあるなら私の勉強不足です。
VirtualLock かしら?
MSDN を確認しても、仮想記憶のコミットで物理記憶ではないという島さんの認識が正しい。
仮想記憶が実際にメモリとページングファイルのどっちにわりあてられるかはWINDOWSが決
めることで物理記憶がオンメモリの保証なんてどこにも書いてない。実装メモリ256MBの環境
で256MBのコミットできるようなAPIだ。それは関数名からも明白。高級OSの動作として
も納得できる。
あまるほどメモリを積んでればオンメモリの可能性は高いが、実行状況によってディスクに落とさ
れる可能性は消えない。アプリには物理領域のコミットなど不可能な以上「可能な限り早く」動作
するためにVirtualAllocする理由はないが、他のメモリ確保に劣る根拠もない。実環
境で比較計測したらいかが?
>確保した領域の先頭から画像が入ってくるので、その入ってきた画像の末端から
>ちょいとオフセットしたところに入ったデータをそのままコピーする。
>で、コピー先で処理をするって方法です。
島さんが懸念するようなドライバの制約などがない限りコピーが無駄。「可能な限りは早く」する
には最初から確保域を2分割して交互に切り替えて使用するべき。
どこを読んだのかね?
以下 MSDNからのコピー
解説
VirtualAlloc 関数
VirtualAlloc 関数は、次の操作のいずれかを実行します。
・以前に VirtualAlloc 関数を呼び出して予約したページ領域をコミットする。
・空きページ領域を予約する。
・空きページ領域を予約し、同時にコミットする。
VirtualAlloc を使って一連のブロックページを予約し、その後 VirtualAlloc を呼び出
して予約済みのページ領域を徐々にコミットできます。この結果、必要が生じるまで物
理記憶域を消費することなく、仮想アドレス空間の一定の範囲を予約できます。
プロセスの仮想アドレス空間内の各ページは、次のいずれかの状態になります。
空き
このページは予約もコミットもされていません。プロセスはこのページにアクセスでき
ません。VirtualAlloc は、空きページの予約、または予約とコミットを同時に行うこと
ができます。
予約済み
このアドレス範囲は、他の割り当て関数から利用できませんが、これらのページはアク
セスできませんし、物理記憶域も関連付けられていません。VirtualAlloc 関数を使っ
て、予約ページをコミットすることができますが、2 回目の予約を行うことはできませ
ん。VirtualFree 関数を使うと、予約ページを解放し、空きページにできます。
コミット済み
このページには物理記憶域が割り当てられていて、アクセス保護コードによってアクセ
スは制御されています。このページの読み取りまたは書き込みを最初に試みた場合にの
み、システムは各コミット済みページを初期化し、物理メモリへロードします。プロセ
スが終了すると、システムはコミット済みページに関連付けられていた記憶域を解放し
ます。VirtualAlloc は、既にコミット済みになっているページをコミットできます。こ
れは、既にコミットされているかどうかにかかわりなく、任意のページ範囲をコミット
できること、およびその場合にこの関数が失敗しないことを意味します。VirtualFree
はコミット済みのページをコミット解除したり、コミット解除と解放を同時に行うこと
ができます。
コミット済み このページには物理記憶域が割り当てられていて、
コミット済み このページには物理記憶域が割り当てられていて、
コミット済み このページには物理記憶域が割り当てられていて、
コミット済み このページには物理記憶域が割り当てられていて、
コミット済み このページには物理記憶域が割り当てられていて、
みえないか? この文字が・・・・
>コミット済み このページには物理記憶域が割り当てられていて、
>
>みえないか? この文字が・・・・
島さんも指摘されていますが。
MEM_COMMIT メモリ内またはディスクのページングファイル内に、指定されたページ
領域に相当する物理的な記憶域を割り当てます。
とMSDNにかいてあります。
物理的記憶域=メモリではありません。
メモリへ固定するには VirtualLock を使います。
皆様はVirtualAllocを使うときに物理メモリ量を考えていないのですか?
そのとおり。
メモリへ固定するには VirtualAllocでコミットしてページにたいして
VirtualLock を使います。
ん?話がかみ合っていないような。
>コミット済み このページには物理記憶域が割り当てられていて、
>
>みえないか? この文字が・・・・
という発言は、Pt-2000さんの
>仮想記憶のコミットで物理記憶ではない・・・
に対してのものだったようですね?
何か勘違いしていました。失礼しました。
>皆様はVirtualAllocを使うときに物理メモリ量を考えていないのですか?
はい、malloc(), new(), GlobalAlloc(), HeapAlloc() いずれの場合でも
主記憶の搭載バイト数は気にしません。どちらかというとページファイルの方が
気になります(仮想記憶なんだから主記憶の搭載量は気にしなくていいよということを
目指しているというのに、なんだか変だと感じます)
>コミット済み このページには物理記憶域が割り当てられていて、
>みえないか? この文字が・・・・
あまり趣味の良くない書き方、言葉遣いですね
2004/09/19(日) 11:26:39 の投稿にそれに関して書いたのですが、どこか変でしたか?
間違いや誤解があるというのならそうはっきり書いてくださいな
頭悪いので、遠まわしな書き方ではさっぱり判りません
気にしないのですね。
自分のアプリのメモリ制限も考えたことないのでしょうね。
画像処理ソフトをお願いできるスキルではないと思います。
べしさん
メモリを取得する関数にはいろいろありますが
300Mバイトという大量データを可能な限り早く処理すると言われているなら
わたしはVirtualallocという選択は正しいと思います。
なぜならVirtualallocはべしさんのような使い方をするために作られたAPIだからです。
malloc関数はAPI HeapAllocを利用しています。
ヒープは、領域が不足すると自動的に拡張を行って拡張をしますが、一度拡張されたヒ
ープは、HeapFree で領域を解放しても元には戻りません。
取得するメモリーのサイズが一定でないときには断片化が発生する可能性が高く、不必
要にヒープサイズが拡大し、システムや他のアプリケーションの動作をを圧迫したり、
システムのパフォーマンス低下を招くことになりかねません。
このため、大量にメモリーを確保して利用しなければならないときのために
VirtualAlloc が存在します。
メモリ管理関数は物理メモリをどう使うかを用途に応じて考えて作られた関数で
物理メモリを無視するためにつくられた関数ではないと思っています。
>ヒープは、領域が不足すると自動的に拡張を行って拡張をしますが、一度拡張されたヒープ
>は、HeapFree で領域を解放しても元には戻りません。(中略)このため、大量にメモリーを
>確保して利用しなければならないときのためにVirtualAlloc が存在します。
たしかにその通りですが、サイズの2倍+αを確保してコピーするというべしさんの設計では
確保は起動時に一度で開放は終了時のみで断片化は考慮不要でしょう。VirtualLockで掴
みつづければ確かにオンメモリですが、他アプリの起動を禁止できないOSですから起動時にロック
に失敗した場合の想定は必要です。そして、常にロックしながら動作するのであれば他アプリの動作
の圧迫など覚悟の上でしょう。システムのパフォーマンスは環境を作っての実測を薦めます。
>メモリ管理関数は物理メモリをどう使うかを用途に応じて考えて作られた関数で
>物理メモリを無視するためにつくられた関数ではないと思っています。
同意します。ただアプリの物理メモリ操作を無制限に認めることはシステムの安定性にもかかわりま
すから制限があることは確かで、高級OS上ではできない事(OSが許可しない事)はできません。
選択肢は複数提供されてますからそれを比較検討すればいいだけで「出来る限り」早くするために出
来ない事を悩んでも仕方ありません。リアルタイムOSのように処理完了時間が保証されるわけでも
ありませんしOSの処理時間は実環境で計測するくらいしかないでしょう。
>仮想記憶なんだから主記憶の搭載量は気にしなくていいよということを
>目指しているというのに、なんだか変だと感じます)
仮想記憶の目的はこれだけではないと思いますし理想と現実も違います。トレードオフを選択できる
のがベストで、一般の小物単発アプリが気にしなくていいのは大きな利点ですが、大量消費や長時間
常駐するようなアプリはいろいろと気にするべきです。これが気にできないとそれは大きな欠点です
からVirtualAllocはこのために存在します。
ドライバ製作も選択肢に入れればより早い手段もあるのかもしれませんが、毎回のコピーが削り所だ
と思う以外にはべしさんの設計は普通だと思います。