多线程下内存分配方式的比较(TCMalloc vs mt_alloc)

 

多线程下内存分配方式的比较(TCMalloc vs mt_alloc)

分类: Libraries   837人阅读  评论(0)  收藏  举报
当软件性能优化到一定程度之后,用vturn查看hotspots,将会发现malloc/delete会花费很高比例的时间,此时如果是多线程程序,频繁的lock将会是一个瓶颈,这里有一篇oracle的文章,很好的介绍了这样的情况http://www.oracle.com/technetwork/articles/servers-storage-dev/mem-alloc-1557798.html

在linux平台,此时我们主要考虑到两种优化方案,各自都有很细节的文章可以参考
1. google的MTMalloc (http://goog-perftools.sourceforge.net/doc/tcmalloc.html)

2. gnu的__mt_alloc (http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch32.html)


下面我做了一个简单的测试程序
[cpp]  view plain copy
  1. // test app  
  2. void* vectormemorycost(void*){  
  3.     cout << "malloc test"<< endl;  
  4.     int blocksize = 512;  
  5.     for(int j=0;j<20; ++j){  
  6.         int sum=25000;  
  7.         char* p1[sum];  
  8.         for(int i=0; i<sum;++i){  
  9.             p1[i]=(char*)malloc(blocksize);  
  10.         }  
  11.   
  12.         for(int i=0; i<sum;++i){  
  13.             free(p1[i]);  
  14.         }  
  15.     }  
  16.   
  17.     return 0;  
  18. }  
  19.   
  20. void* mtallocateMemorycost(void*){  
  21.     cout << "mt alloc test"<< endl;  
  22.     typedef pod value_type;  
  23.     typedef __gnu_cxx::__mt_alloc<value_type> allocator_type;  
  24.     typedef __gnu_cxx::__pool_base::_Tune tune_type;  
  25.   
  26. ///_M_align(__align)  
  27. ///_M_max_bytes(__maxb)  
  28. ///_M_min_bin(__minbin),  
  29. ///_M_chunk_size(__chunk)  
  30. ///_M_max_threads(__maxthreads),  
  31. ///_M_freelist_headroom(__headroom)  
  32. ///_M_force_new(__force)  
  33.   
  34.     tune_type t_our(16, 510, 32, 5120, 20, 10, false);  
  35.     allocator_type a;);  
  36.     a._M_set_options(t_our);  
  37.     int blocksize = 512;  
  38. for(int j=0;j<20; ++j){  
  39.     int sum=25000;  
  40.     allocator_type::pointer p1[sum];  
  41.     for(int i=0; i<sum;++i){  
  42.     p1[i]=a.allocate(blocksize);  
  43.     }  
  44.   
  45.     for(int i=0; i<sum;++i){  
  46.     a.deallocate(p1[i], blocksize);  
  47.     }  
  48. }  
  49.     return 0;  
  50. }  
  51.   
  52.   
  53.   
  54.   
  55. typedef void*(*pFoo)(void*);  
  56.   
  57. void mtallocatePrivate(pFoo func){  
  58.     int i;  
  59.     int cores = 4;  
  60.     pthread_t threads[cores];  
  61.     /* Create threads to do the work. */  
  62.     for (i = 0; i < cores; ++i)  
  63.         // pthread_create (&(threads[i]), NULL, vectormemorycost, NULL);  
  64.         pthread_create (&(threads[i]), NULL, func, NULL);  
  65.   
  66.     /* Wait for all threads to finish. */  
  67.     for (i = 0; i < cores; ++i)  
  68.         pthread_join (threads[i], NULL);  
  69. }  
  70.   
  71. void mtallocate(){  
  72.     for(int i=0;i<5;++i){  
  73.         mtallocatePrivate(mtallocateMemorycost);  
  74.         mtallocatePrivate(vectormemorycost);  
  75.     }  
  76. }  




改变的tune_type参数,发现gnu的最优的情况比malloc快一两倍,最糟糕的情况是反而比malloc慢十倍,很依赖具体的实现情况,另外tcmalloc使用很简单,我们只要改一下link的库,测试的结果是比不用tcmalloc有七八倍的性能提高,从结构上来讲gnu的在更高层次的代码上优化,想通过memory pool和thread id的比较来减少申请内存的次数和不同线程之间的竞争,它最终调用的还是malloc尤其是当申请的内存大于_M_max_bytes的时候就完全是调用malloc了,而TCMalloc是替换掉了系统的malloc,是更加底层的优化。

总结一下,gnu的使用麻烦,接口繁琐,还可能有负面效应,google的比gnu的速度快,使用也方便很多。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值