動的頂点バッファのNoOverwriteとDiscardの記事への質問とその回答
ひにけに #XNAに「動的頂点バッファのNoOverwriteとDiscard」( http://bit.ly/jDZsN9 )を投稿しました。
2011-05-23 15:11:27@Higeneko この記事の解説によると、Discardオプションを使用してSetDataでVertexBufferを書き換えると、VRAMの断片化が進むということになりますね。
2011-05-23 15:35:46@Higeneko 確保/解放が連続ということですが、確保が先で、解放があとになりますよね。すると、メモリのアドレスが変わるということになる。つまり元のアドレスのバッファは使用されない領域となり、そこは断片化しているのでは?
2011-05-23 15:46:47@junzabroP そして、次のフレームで確保が必要になった時には前に解放されていた部分の空きサイズが同じなので、そこが使用されて断片化もなくなります
2011-05-23 15:49:33@Higeneko なぜ次のフレームで確保されるのでしょうか? SetDataを呼び出したタイミングではないのでしょうか。SetDataもコマンド化されるだけということなのかな。
2011-05-23 15:50:43@junzabroP 例えば最初に確保した領域をAとします。次にDiscardで自動的に確保される領域をBとします。この段階で確保されているメモリはA,Bとなり、GPUがAのリソースを使い終わるとAが解放されます
2011-05-23 15:53:30@junzabroP 次のフレームでDiscardすると、今度は解放されたAの領域を再利用し、Bの領域が解放され、元の状態に戻ります。
2011-05-23 15:55:37@junzabroP 要するにDiscardを設定するということは、一定のメモリ確保、解放のパターンが連続することになるのでドライバ側で単純なキャッシュ処理をすることでメモリ断片化を防ぐことができるのが利点となります
2011-05-23 15:56:48@Higeneko なるほど。次のフレームで同じ呼び出しをすることが前提なわけですね。私の実装したシステムではIndexBufferもプリミティブごとに用意するし、テクスチャは不要になればすぐ解放する動作のままです。やはり断片化しそうな気がします。
2011-05-23 15:57:42とはいえ、Vertex/IndexBufferを事前確保してこの部分で断片化を防いだとしても、やはりOutofmemoryエラーは出てしまうんだよな。おそらくTexture/RenderTarget Textureの確保でも事前確保が必要なのだろう。
2011-05-23 15:59:30@junzabroP それは、結構きついですね。PCだと大丈夫かもしれませんが、単純なメモリ管理機能しかないコンシューマー機だとメモリ断片化に苦しみそうです。
2011-05-23 16:03:37@Higeneko いやー、お恥ずかしながら、不十分なんです。しかもゲームプログラム側でなく、ビデオカード側のドライバの品質面で。RADEONでは256MBあってもだめだったりする(と言ってもRD9600)。一方、インテルではそういったことは起こりにくい。
2011-05-23 16:05:21私は大体、メモリ確保の粒度とタイミングを決めといて断片化を起こさないようにしています。っていうか、Xbox 360の場合は自分で作ったメモリ管理方法が使えたりするので「このリソースはこの領域から」みたいに管理することもできるんですけどね
2011-05-23 16:06:09@junzabroP Radeon 9600の世代だと、頂点バッファの切り替えとかにもコストが掛かるのでインデックス、頂点共にまとめておかないとパフォーマンスが出なかったりするので、特化させるんだったら自前のメモリ管理しないとキツイかもしれませんね
2011-05-23 16:17:44@Higeneko VertexBufferの切り替え自体のコストですか……。そこまでは検討していませんでした。というかそんなものにコストがかかっていたのか……。とはいえ、30000超えのIndexBufferなどもありますので、全部をまとめるのは無理ですね。
2011-05-23 16:19:22@Higeneko 先ほど少しお話ししましたが、GUIの各パーツについて、全ての状態を1つづりのVertex/IndexBufferにまとめ、IndexBufferを毎回書き換える方法で描画しています。なので、中は実際にはスカスカなんです。
2011-05-23 16:27:49@junzabroP それも厳しいです(物言いばっかりでごめんなさい、決して悪気はありません)、それだと頂点キャッシュのヒット率が皆無に等しくなるので、逆にインデックスバッファ固定、頂点バッファを書き換える方が速いと思います
2011-05-23 16:34:58