newのカスタマイズ

今日は研究室で地味にシミュレータ作成の続き。イベントのメモリをその都度要求せずに、プールしてそれを順次切り売りする仕様に変更。予想以上に高速化したのでうれしい限り。newのカスタマイズなんてのはメモリを自動管理してくれる親切なjavaにはできない芸当。パケットの廃棄率とかを議論しようとすると、パケットが10の8乗くらいはいりそうやから、さらにそれに付随するイベントはその数倍くらいは必要になるわけで。さすがに毎回メモリ確保して開放してたのではやってらんねーかなぁと。今までそんなアホみたいにメモリ使うようなプログラム書いたことなかったもんやから、勉強になる。うーん、でも予想以上にいいかんじになったんでやった甲斐あり。こんなことしてるからまだフレームワークばっかりで本体作るのに手をつけられてないんやけど。まぁぼちぼち。ぼちぼち。夕方からバイト行った。

参考までに具体的にどーやるかを書いておくと、はじめに大量のメモリを確保して固定区画に分割して、それを連結リストで管理。メモリ確保要求の度にそこから一つもらう。で、不要になったら返すを繰り返す。はじめ俺もそれでやるつもりやったんやけど、このままでは単純すぎて、あらかじめ最大要求数がわかってないといかんとゆーところが今回の場合使う上で一番困る。やから、メモリを使い切ったらさらに新しい領域を確保して連結リストに補充せねばならん。
そんなことを考えてたらboost::poolなんてまさにまんまなのがあるやんとゆーことに気付く。さすがboostえーのあるやん。で、これが使えそうかなと、さっそく試しにint10万個ほど生成と削除を10回ほど繰り返してみたところ。資源の乏しそうなノートでは20倍以上の差が。おそるべし。
でも、公式とかその他のWebも説明が不親切かつサンプルプログラムがまったくもって実用性のない簡単な例なので困る。何が困るかとゆーと、基本的にイベントなんてもんはいろんな種類があって、抽象的なインターフェイスから派生して使うことを前提としてるわけで、派生クラスのサイズはそれぞれ異なる。となると、要求する領域のサイズも変わるわけで。かといって可変区画の管理なんて高度なテクはできず。結局どうするかとゆーと、イベントの派生クラスとしてあらかじめ内部にダミーの作業領域を持ったイベントを定義して、適当に最大サイズのイベントを作る。このサイズでメモリを要求することにする。これが固定区画の単位サイズとなる。んで、その領域上に具体的なイベントのオブジェクトをマップする。よーするに、イベントの基底クラスにstaticにboost::poolを持たせて、基底のoperator newを上書きしてpoolからメモリを取得して返すように変更。こーすると、このメモリ領域上にコンストラクタがオブジェクトを構築してくれる。operator deleteも同様に上書きして不要な領域をpoolに返すようにする。
こんなかんじで実装しとくと、実際にイベントを生成する場合はメモリ管理がどーなってるとか特に気にせず、いつもどおり普通にnewするだけ。暗黙のうちにカスタマイズされたnewが呼ばれて高速にメモリが割り当てられる。実際やってみると思ってたよかいいかんじ。