boost poolとsmart pointer
boost poolを調査中です。
私の場合、クリティカルな速度よりもメモリの断片化が怖いのだけなので、単純な使い方を見ているだけですがヽ(;´Д`)ノ
色々と調べてみて分かったのですが、boost poolでは、使ったメモリは自分でプールに戻さないと(´・д・`) ダメなようです。
スマートポインタに慣れきっている私には、チトきつ過ぎる(ノД`)シクシク
という分けて、スマートポインタのdeleterを使って自動的に解放してくれる便利関数を作成しました。
まず、今回作成した便利関数群は以下となります。
まぁ、削除子を追加しただけですがヽ(;´Д`)ノ
//! object pool を使いやすくする関数群 namespace pool_utility { namespace { //! object 解放子 template< typename OBJECT_TYPE , typename POOL_TYPE > struct singleton_pool_deleter { void operator () ( OBJECT_TYPE * p ) const { POOL_TYPE::free(p); } }; } //! object poolからメモリを借りる template < typename POOL_TYPE > inline std::unique_ptr< typename POOL_TYPE::tag::OBJECT_TYPE , singleton_pool_deleter< typename POOL_TYPE::tag::OBJECT_TYPE , POOL_TYPE > > borrow_unique_object( void ) { typedef typename POOL_TYPE::tag::OBJECT_TYPE OBJECT_TYPE; return std::unique_ptr< OBJECT_TYPE , singleton_pool_deleter< OBJECT_TYPE , POOL_TYPE > > ( ( OBJECT_TYPE * )POOL_TYPE::malloc() , singleton_pool_deleter< OBJECT_TYPE , POOL_TYPE >() ); } //! object poolからメモリを借りる template < typename POOL_TYPE > inline std::shared_ptr< typename POOL_TYPE::tag::OBJECT_TYPE > borrow_shared_object( void ) { typedef typename POOL_TYPE::tag::OBJECT_TYPE OBJECT_TYPE; return std::shared_ptr< OBJECT_TYPE > ( ( OBJECT_TYPE * )POOL_TYPE::malloc() , singleton_pool_deleter< OBJECT_TYPE , POOL_TYPE >() ); } }
使い方は以下となります。
注意が必要な箇所としては、poll識別用のtagに「OBJECT_TYPE」というメンバ型が必要な事です。
この型を使って、プールが確保している型情報を取得しています。
#include <future> #include <boost/pool/singleton_pool.hpp> namespace { //! pool対象となるオブジェクト struct Hoge { char data[1024]; int i = 0; }; //! poolを識別するためのタグ struct Hoge_Tag { //! プールが保持しているデータの型を取得 typedef Hoge OBJECT_TYPE; }; //! オブジェクトプールを生成 typedef boost::singleton_pool< Hoge_Tag , sizeof( Hoge_Tag::OBJECT_TYPE ) > my_pool; //! 負荷関数 void unique_test( void ) { while(true) { for (int i = 0; i < 10000; ++i) { auto t = pool_utility::borrow_unique_object< my_pool >(); std::fill( t->data , t->data + 1024 , '0'); t->i = i; } } } //! 負荷関数 void unique_test( void ) { while(true) { for (int i = 0; i < 10000; ++i) { auto t = pool_utility::borrow_unique_object< my_pool >(); std::fill( t->data , t->data + 1024 , '0'); t->i = i; } } } //! 負荷関数 void shared_test( void ) { while(true) { for (int i = 0; i < 10000; ++i) { auto t = pool_utility::borrow_shared_object< my_pool >(); std::fill( t->data , t->data + 1024 , '0'); t->i = i; } } } } int main() { auto f1 = std::async( std::launch::async , unique_test ); auto f2 = std::async( std::launch::async , shared_test ); f1.get(); f2.get(); }