目的:
针对自己的一个内存池如何测试其性能.
介绍:
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
关于实现有疑问和建议,可以提出宝贵的意见。。