modern 发表于 2010-7-14 19:19:52

对ACE与Boost内存池的性能比较

本帖最后由 modern 于 2010-7-15 08:37 编辑

分别测试了系统New/Delete,boost::pool,ACE_Local_Memory_Pool,
ACE_Cached_Allocator以及根据ACE_Cached_Allocator修改了之后可自动伸缩池大小的内存池等。
测试基准
1.是否使用锁
2.累计分配释放1000万次
3.分别测试内存池大小为20000,50000。
4.是否预分配
5.随机分配1-1024大小的内存块,分配指定的复杂对象。
6.优化开关为O2
7.内存分配之后,为了避免编译器自动优化,内存块根据分配的内存块大小,做了memcpy
指定对象,调用了函数,内部对全局调用次数加1。

主要的测试结果(时间开销):
一.OSNew无锁,内存池有锁的情况下。
1.随机分配1-1024大小的内存块
A.boost::pool(3796ms)与ACE_Cached_Allocator(3796ms)性能最好,相差无几。
分配性能与测试内存块的最大规模无关。
但是boost::pool的优点是自动扩展,无须预分配。

B.修改后自动伸缩池大小的ACE_Cached_Allocator性能
20000最大规模的内存池较boost::pool相差大概10%
50000最大规模的内存池较boost::pool相差大概一倍。
显然后者不太令人满意,不过因为这里是手动修改的,
所以应该还有优化的空间,算法实现是与链表的长度无关的。
C.ACE_Local_Memory_Pool
20000最大规模的内存池较boost::pool相差大概15%
50000最大规模的内存池较boost::pool相差大概50%。
ACE_Local_Memory_Pool的优点在于内存的利用率更高。
D.OSNew由于未使用锁6125ms,大概慢了30%

2.分配指定大小的复杂对象
ACE_Local_Memory_Pool与boost::pool性能差异不大。
ACE_Cached_Allocator性能最好大概节省了1/4的时间开销。
修改后自动伸缩池大小的ACE_Cached_Allocator性能要慢20%。
OSNew时间开销大概接近3倍。

二.无锁的情况下
1.最大20000大小的内存池随机分配1-1024大小的内存块
几种内存池的性能差异比值基本不变。
OSNew依然未使用锁6062ms,大概慢了50%
2.最大20000大小的内存池分配指定大小的复杂对象
ACE_Cached_Allocator与boost::pool性能最好且差异不大大约300ms。
修改后自动伸缩池大小的ACE_Cached_Allocator性能要略慢437ms。
ACE_Local_Memory_Pool大概在718ms
同样OSNew仍然需要2700+ms

总结:
boost::pool在各方面的平均性能均要好一些,而且可自动增长池的大小,
唯一的缺点是无法自动降低池的大小。
ACE_Cached_Allocator对于固定池大小的情况下略有优势。
修改后的ACE_Cached_Allocator可自动伸缩池的大小,缺点是性能稍差,不过大多时候仍尚可接受,
另外我在测试中基本上解决了遇到的bug,但是最近估计没有时间对内存池规模50000的情况下进行优化了。
http://www.acejoy.com/bbs/viewthread.php?tid=2584&extra=page%3D1
ACE_Local_Memory_Pool的优点是内存利用率较高,尤其是随机分配不定长大小的内存块时候,
但是同比性能要又差了一些,做得检查多了,这可以理解。

最后,测试代码中使用了较多的模版进行抽象,因此如果有好的内存池,
可以相当较为容易的插入到测试代码中对比。
下面是源代码

modern 发表于 2010-7-14 19:31:35

测试结果。

freeeyes 发表于 2010-7-20 13:28:28

ACE的cache和mempool似乎也不能降低

modern 发表于 2010-7-20 15:35:47

你是说自动减少内存池已分配内存的大小么?看这里
// Inserts an element onto the free list (if we are allowed to manage
// elements withing and it pasts the high water mark, delete the
// element)

template <class T, class ACE_LOCK> void
ACE_Locked_Free_List<T, ACE_LOCK>::add (T *element)
{
ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));

// Check to see that we not at the high water mark.
if (this->mode_ == ACE_PURE_FREE_LIST
      || this->size_ < this->hwm_)
    {
      element->set_next (this->free_list_);
      this->free_list_ = element;
      this->size_++;
    }
else
    delete element;
}

dynasty_ding 发表于 2014-6-14 19:45:07

如果用boost的thread_pool管理 ace的 message_block,采用 construct和free,多线程情况下,过一下就会异常

nettoobad 发表于 2015-9-9 22:44:22

内存池的应用要分场合的,对于ACE_Message_Block没必要用
页: [1]
查看完整版本: 对ACE与Boost内存池的性能比较