從最簡單的入手
1.實現一個固定大小的allocator
//分配固定大小記憶體塊的模板類,內部緩衝演算法自己實現了,
//我用的是預分配+回收cache鏈
//即分配時先檢查回收鏈有無資料,無的話每次分配n*size個塊,然後返回其中一個,直到該塊用完後繼續分配
//釋放時直接加入回收鏈即可
//好處是速度夠塊,但是浪費空間可能就比較大了
template <size_t size> class Fix_Allocator{
void* alloc(size_t size);
void free(void*p);
typedef Fix_Allocator me;
static me Instance;
};
提供一個給host class用的impl template
template <class Host> class new_op{
void* operator new(size_t size);
//........
};
template <
typename Host
>
inline void* new_op<Host>:: operator new(size_t size){
return Fix_Allocator<sizeof(Host)>::Instance.alloc(size);
}
然後所有需要記憶體池的類繼承new_op即可
class cls_usePool:public new_op<cls_usePool>{
.........
};
2.改進
以上方法的不足,大小近似的類不能共用記憶體池,如sizeof(clsA)==11,sizeof(clsB)==12,
記憶體池並不能提高程式太多效率.
我用的辦法是將所有分配大小對齊到2的冥(這樣最大記憶體佔用將會接近原來的一倍,考慮(17,33這樣大小的對像很多的情況)
解決方案如下
template <bool flag, typename T, typename U>
struct TypeSelectT
{
private:
template<bool>
struct In
{ typedef T Result; };
template<>
struct In<false>
{ typedef U Result; };
public:
typedef typename In<flag>::Result Result;
};
#define countof(x) (sizeof(x)/sizeof(x[0]))
template <int x,int y>
struct extr{
protected:
template <int x1>
struct imp{
enum {
next=(x1+y-1)/y,
};
enum {Result=1+imp<next>::Result};
};
template <>struct imp<1>{
enum {Result=0};
};
public:
enum {Result=imp<x>::Result};
};
template <int x,int y>
struct pwr{
protected:
template <int y1>
struct imp{
enum{
next=y1-1
};
enum{
Result=x*imp<next>::Result
};
};
template<> struct imp<0>{
enum{
Result=1
};
};
public:
enum{
Result=imp<y>::Result
};
};
template <int size>struct allocIdx{
template <int idx> struct table{
// enum{ }
struct accept{
enum{ Result=0};
};
struct Overflow{
enum{ Result =1};
};
enum {
k
// Result =TypeSelectT< (idx>=0)&&(idx<countof(allocTable)),accept,Overflow>::Result::Result
};
};
};
先用extr算sizeof(cls)最接近2的多少次冥n,然後用pwr計算2的n次冥的值
最後用n查allocidx表得到該大小下,記憶體塊的cache數.
最後將這些值傳遞給new_op的方法
這樣就做到了11 12 13大小的對像全部共用16的allocator,而且是靜態繫結的.