勤能补拙,Expter

成都游戏Coder,记录游戏开发过程的笔记和心得!

针对一个内存池测试相关介绍

目的:
针对自己的一个内存池如何测试其性能.

介绍:
1.内存池测试用例的选取.
1.单线程的分配和释放.
2.内存回收.
3.性能关注.

关于内存池的设计和实现网上遍地都是,本文不具体介绍关于内存池的具体实现和方式,主要是介绍设计一个内存池怎样去测试其性能和安全处理,有一个开源的内存池项目tcmalloc也有介绍很多,但是为了满足多种需求,代码过于庞大,最后我用来测试分配性能测试。

1个内存池的测试用例应该包含:
1)该项目内存分配概率随机性.
2)同时保证释放的随机性.
3)可以支持多种分配方式(不同大小,不同对象参数等).


要达到上面要求则可以设计
1.一个数组来设定需要分配的大小。
   long  arr[ ] = { 16,32,64,128,256,512,1024,2048,5120,5130,7000,6000,10240,15000,20000};

2.根据需求来指定各个大小的分配几率,这好比有多少概率选中某个数(需特定的分配):
   

 A.针对这个需求可以设定定一个概率数组Odds,数组值arrArr的索引。
    B.针对Odds指定数组数据,使其数据分配达到arr需要分配概率。
       
///   被分配的概率
       long  Odds[ ] = 0,0,0,1,1,2,2,2,3,3,4,4,4,4,5,5,5,5,6,6,,7,7,7,8,8,8,8,9,9,9,10,10,11,12,12};
    C.随机Odds数组,然后得到其值分配,其值则为Arr的索引。
        
long  Asize= arr[ Odds[ rand()%size ] ] ;



3.释放保证随机性。
     什么时候释放,以及分配了做什么用,都是又应用层决定的,所以需要把分配出来的内存通过一个容器来存储.
     由于分配是随机性,那么释放的时候也保证了随机性。

4.支持多种分配方式。
     A. 对象分配:     

MemFactory  Memory;

    A
* a = Memory.Alloc<A>( );
    B
* b = Memory.Alloc<B,int>2 );

    Memory.FreeObj( a );
    Memory.FreeObj( b );

    B.直接分配

void* p1 = Memory.Alloc( Asize );


5.性能测试
   为了测试性能,我选择了分配1000W次,其中用一个容器保存分配的数据,然后当容器到达100W的时候释放60W数据(保证数据正在使用,随机释放)。
   下面的Alloc time 只是统计的Alloc时间累加,Free time只是统计的Free 时间累加,Total time记录这次测试总共花费时间。

 1测试结果如下:
 2MemPool Alloc time 3242 ms  Free time: 2412 ms Total time 22535 ms
 3System    Alloc time 33616 ms Free time: 6676 ms Total time 55013 ms
 4TCMalloc Alloc time 3451 ms   Free time 1896 ms  Toal  time 21078 ms
 5
 6可以看到TCMalloc的分配和释放都比较快。。
 7
 8其中arr每个分配的大小命中概率。
 9Count[ 1 ] = 2436395
10Count[ 2 ] = 1281728
11Count[ 3 ] = 1026009
12Count[ 4 ] = 769123
13Count[ 5 ] = 768911
14Count[ 6 ] = 769335
15Count[ 7 ] = 640757
16Count[ 8 ] = 640974
17Count[ 9 ] = 512378
18Count[ 10 ] = 384841
19Count[ 11 ] = 256135
20Count[ 12 ] = 257367
21Count[ 13 ] = 256047



PS:
1.内存池的使用:
  

   一般情况下内存池,是整理一整块内存,然后通过一个list串连起来,然后分配的时候从链表中获取,释放也是插入到链表中。
    为了方便多对象的多参数以及无参数的分配,可以一些列宏和模板来实现:
    
    具体的可以参考后面附带的内存池实现的代码:
    
    
#define DEFINE_CALL_CON( paramcount ) template <class T, DP_STMP_##paramcount( typename, tp ) >\
    inline T 
* Alloc(DP_MTMP_##paramcount( tp, p ) ){\
           unsigned 
long lSize = sizeof(T);\
           
void* ptMem = Alloc(lSize);\
         
if!ptMem) return NULL; \
          T 
* pt = new(ptMem)T( LP_SNMP_##paramcount( p ) );\
         
return pt;\
      }

    
    A. 对象分配:      
    MemFactory  Memory;

    A
* a = Memory.Alloc<A>( );
    B
* b = Memory.Alloc<B,int>2 );
    C* c = Memory.Alloc<C,int,const char*>(1,"dd");
    Memory.FreeObj( a );
    Memory.FreeObj( b );
       Memory.FreeObj( c );

    B.直接分配
    
void* p1 = Memory.Alloc( Asize );
        memset(p1,0,ASize);


2.内存池的代码:
   1)   实现全是利用的freelist,减少内存开销,分配速度,直接定位。
   2)   管理都是通过工厂类来同一的管理。
   3)   指定分配策略.

   源码为Vs2008版本...

   /Files/expter/Pool.rar

关于实现有疑问和建议,可以提出宝贵的意见。。

posted on 2011-01-18 21:20 expter 阅读(3411) 评论(3)  编辑 收藏 引用 所属分类: 其他学习笔记工作笔记生活笔记算法与数据结构Visual C++ 笔记

评论

# re: 针对一个内存池测试相关介绍 2011-01-19 02:33 电脑知识与技术博客

太有技术性了。好知识学习了  回复  更多评论   

# re: 针对一个内存池测试相关介绍 2011-01-22 23:59 egmkang

兄弟有没有试过tcmalloc??  回复  更多评论   

# re: 针对一个内存池测试相关介绍 2011-01-23 20:00 expter

@egmkang
试过,上面不是有测试吗?
tcmalloc在处理大块内存的时候浪费较多。。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理