BREWでメモリエラー(2)

kanokeさんのblog(id:kanoke:20050503)にて、BREWでメモリエラーが発生した場合に、エラー画面を表示して終了させる方法を公開しています。
キタ━━━━ヽ(゜∀゜ )ノ━━━━!!!!
なるほど、普段はmallocで確保しつつ、失敗した場合、1フレーム分だけ、あらかじめ確保しておいた領域から渡すわけですね。無事1フレームを耐えきれば、メモリエラーが出て、終了するようにするみたいです。
で、問題になるのが、どうやって1フレームを耐えきるか。
kanokeさんとは別のアプローチで考えてみました。


まず、poolしておいたメモリ以外に、その空き領域を管理するための領域をpoolしておきます。
この空き領域管理メモリは、空き領域の位置と、その大きさを、複数持っています。
で、先頭や後方に確保すれば、空き領域の位置と、その大きさを変更します。
(まずやりませんが)中間に確保すれば、空き領域の位置と、その大きさのデータを追加して、2つの領域を管理します。
解放された場合に、空き領域が連続するのであれば、パージします。
こうやってすれば、かなり32KBをオーバーする確率は少なくなる気がします。
で、ここで問題なのが、空き領域管理メモリのサイズ。
まじめに考えると、空き領域の位置が4Byte、その大きさが2Byteとすれば、1つの空き領域が6Byte。空き領域の数が最大になるのが、1Byte確保して、1Byte空いているという形の繰り返し。これだと、32KB/(1+1)=16384個の空き領域を管理しないとダメなので、6*16384で、98304。
つまり、96KBもの領域を使用します(;´Д`)
……こんなことするぐらいなら、メモリ管理をせずに、128KBの領域を最初に確保します(;´Д`)
これをどうするかですが、ちゃんと考えてみると、空き領域の位置は、poolしたメモリの先頭からのオフセットでいいので、2Byteでいいですね。
で、領域は32Byteごとに分割して使うことにしましょう。
そうすれば、1Byteを確保しようとした場合も、32Byteの領域が使用されます。
なので、必要な領域は、空き領域の位置が2Byte、その大きさが2Byteで、1つの空き領域が4Byte。空き領域の最大数が、32KB/(32+32)=512個なので、512*4=2048となり、2KBで済みます。
512個以上の領域が確保出来ないのが気になりますが、1フレームの間にはさすがに起こらない……と思いたいです(;´Д`)
でも実装するのがメンドー(;´Д`)


追記:
そういえば、空き領域を管理する領域については、別にpoolしなくても、クラスの中で配列をメンバに持っておけば問題ないかな(;´Д`)


追記2:
あと、空き領域の位置と大きさは2Byteずつで取ってますが、32Byteで分割するのであれば、32KB/32Byte=1024なので、10bitで表現出来ます。つまり20bitあればいいのです。
ですから、空き領域と大きさを合計して、3Byteあれば十分です。ということで、poolして3Byte区切りに使うことにしましょう。
そうすれば、512*3=1536Byteで済みます。
なんか4bitほど勿体ない気がしますが、この辺は適当に弄ります(;´Д`)
まあ、実際には、これを管理するための変数が、あと数Byte必要そうですね。これはメンバに追加しておきます。
あ、メンバに追加しなくても、4bitの領域を、この辺のフラグにしても良いかも。


追記3:
32Byteではなく、8Byteで分割すれば、32KB/8Byte=4096で、12bitで計算することになり、4bitの余りが無くなるので、3*2048=6KBとなり、効率が一番良いかもしれませんね。


とりあえず今やってる仕事を片づけたらやってみよっと(;´Д`)