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

当软件性能优化到一定程度之后,用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)


下面我做了一个简单的测试程序
// test app
void* vectormemorycost(void*){
    cout << "malloc test"<< endl;
    int blocksize = 512;
    for(int j=0;j<20; ++j){
        int sum=25000;
        char* p1[sum];
        for(int i=0; i<sum;++i){
            p1[i]=(char*)malloc(blocksize);
        }

        for(int i=0; i<sum;++i){
            free(p1[i]);
        }
    }

    return 0;
}

void* mtallocateMemorycost(void*){
    cout << "mt alloc test"<< endl;
    typedef pod value_type;
    typedef __gnu_cxx::__mt_alloc<value_type> allocator_type;
    typedef __gnu_cxx::__pool_base::_Tune tune_type;

///_M_align(__align)
///_M_max_bytes(__maxb)
///_M_min_bin(__minbin),
///_M_chunk_size(__chunk)
///_M_max_threads(__maxthreads),
///_M_freelist_headroom(__headroom)
///_M_force_new(__force)

    tune_type t_our(16, 510, 32, 5120, 20, 10, false);
    allocator_type a;);
    a._M_set_options(t_our);
    int blocksize = 512;
for(int j=0;j<20; ++j){
    int sum=25000;
    allocator_type::pointer p1[sum];
    for(int i=0; i<sum;++i){
    p1[i]=a.allocate(blocksize);
    }

    for(int i=0; i<sum;++i){
    a.deallocate(p1[i], blocksize);
    }
}
    return 0;
}




typedef void*(*pFoo)(void*);

void mtallocatePrivate(pFoo func){
    int i;
    int cores = 4;
    pthread_t threads[cores];
    /* Create threads to do the work. */
    for (i = 0; i < cores; ++i)
        // pthread_create (&(threads[i]), NULL, vectormemorycost, NULL);
        pthread_create (&(threads[i]), NULL, func, NULL);

    /* Wait for all threads to finish. */
    for (i = 0; i < cores; ++i)
        pthread_join (threads[i], NULL);
}

void mtallocate(){
    for(int i=0;i<5;++i){
        mtallocatePrivate(mtallocateMemorycost);
        mtallocatePrivate(vectormemorycost);
    }
}




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

总结一下,gnu的使用麻烦,接口繁琐,还可能有负面效应,google的比gnu的速度快,使用也方便很多。

你可能感兴趣的:(多线程下内存分配方式的比较(TCMalloc vs mt_alloc))