`
febird
  • 浏览: 246961 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

memory pool 的高效实现(代码)

    博客分类:
  • C++
阅读更多

mpool.h

mpool.c

 

 

BenchMark

#include <vector>

#include <febird/c/mpool.h>
#include <febird/profiling.h>

void bench(int n)
{
	using namespace std;

	std::allocator<sample_data> stdal;
	struct fixed_mpool fmp = {0};
	fmp.cell_size = sizeof(sample_data);
	fmp.chunk_size = 8192;
	fmp.nChunks = 1024;
	fixed_mpool_init(&fmp);

	febird::profiling prof;

	vector<sample_data*> vp0(n), vp1(n);

	long long t0, t1, t2, t3, t4, t5, t6;
	t0 = prof.current();
	for (int i = 0; i+3 < n; i+=4)
	{
		vp0[i+0] = stdal.allocate(1);
		vp0[i+1] = stdal.allocate(1);
		vp0[i+2] = stdal.allocate(1);
		vp0[i+3] = stdal.allocate(1);
	}
	t1 = prof.current();
	for (int i = 0; i+3 < n; i+=4)
	{
		vp1[i+0] = (sample_data*)fixed_mpool_alloc(&fmp);
		vp1[i+1] = (sample_data*)fixed_mpool_alloc(&fmp);
		vp1[i+2] = (sample_data*)fixed_mpool_alloc(&fmp);
		vp1[i+3] = (sample_data*)fixed_mpool_alloc(&fmp);
	}
	t2 = prof.current();
	for (int i = 0; i+3 < n; i+=4)
	{
		stdal.deallocate(vp0[i+0], sizeof(sample_data));
		stdal.deallocate(vp0[i+1], sizeof(sample_data));
		stdal.deallocate(vp0[i+2], sizeof(sample_data));
		stdal.deallocate(vp0[i+3], sizeof(sample_data));
	}
	t3 = prof.current();
	for (int i = 0; i+3 < n; i+=4)
	{
		fixed_mpool_free(&fmp, vp1[i+0]);
		fixed_mpool_free(&fmp, vp1[i+1]);
		fixed_mpool_free(&fmp, vp1[i+2]);
		fixed_mpool_free(&fmp, vp1[i+3]);
	}
	t4 = prof.current();
	for (int i = 0; i < n; ++i)
	{
		stdal.deallocate(stdal.allocate(1), sizeof(sample_data));
	}
	t5 = prof.current();
	for (int i = 0; i < n; ++i)
	{
		fixed_mpool_free(&fmp, fixed_mpool_alloc(&fmp));
	}
	t6 = prof.current();

	printf("alloc[std=%lld, my=%lld, std/my=%f], free[std=%lld, my=%lld, std/my=%f], alloc+free[std=%lld, my=%lld, std/my=%f]\n"
		, prof.us(t0,t1), prof.us(t1,t2), (double)prof.us(t0,t1)/prof.us(t1,t2)
		, prof.us(t2,t3), prof.us(t3,t4), (double)prof.us(t2,t3)/prof.us(t3,t4)
		, prof.us(t4,t5), prof.us(t5,t6), (double)prof.us(t4,t5)/prof.us(t5,t6)
		);

	fixed_mpool_destroy(&fmp);
}

int main(int argc, char* argv[])
{
	bench(1000000);
	return 0;
}

 

Windows7 + visual C++ 2008

 

time in us

std::allocator(new/delete)

fixed_mpool

fast ratio

alloc

93901

15416

6.091139

free

70657

7374

9.581909

alloc+free

131739

9297

14.170055

Linux

uname:

Linux 2.6.9-78.ELsmp #1 SMP Wed Jul 9 15:46:26 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux

 

time in us

std::allocator(pooled)

fixed_mpool

fast ratio

alloc

92779

26734

3.470450

free

42564

17224

2.471203

alloc+free

50089

9088

5.511554

 

分享到:
评论
16 楼 mathgl 2010-04-08  
单线程也没啥不好。。用co routine 用消息传递 信息好了嘛...
15 楼 huxk 2010-04-07  
樓主非常牛逼
14 楼 Arath 2009-12-02  
febird 写道
目前不支持多线程,keep it simple stupid.
多线程需要考虑的东西太多了,每次alloc/free都加锁,开销太大,仅在溢出时才加锁,又太复杂。真需要多线程,还是用通用的。


如果这样,那么应用的范围就会小很多,类似bucket的memory pool实现挺多,一般都是考虑多线程的.
不过能动手自己做一个,总是好的~
btw,我也喜欢自己在程序中自己写memory pool,一个吗是买商业的太贵,二则也是觉得自己写一个用起来方便。
另外还有一个很大的好处,可以把memory的错误统一处理掉,上层代码可以简练很多.
13 楼 febird 2009-12-02  
目前不支持多线程,keep it simple stupid.
多线程需要考虑的东西太多了,每次alloc/free都加锁,开销太大,仅在溢出时才加锁,又太复杂。真需要多线程,还是用通用的。
12 楼 Arath 2009-12-02  
lz可以做一下多线程下的效率测试.
简单说定制的memory pool肯定是最快的,但是通用的因为考虑的东西多所以效率上肯定要差一点.
而且自己写的memory pool缺乏自我调适机制,会让你的程序在排查leak的时候增加难度.
11 楼 febird 2009-12-02  
sunzixun 写道
mp->max_cell_size = (mp->max_cell_size + MPOOL_MIN_CELL - 1) / MPOOL_MIN_CELL * MPOOL_MIN_CELL;  


为什么要 除以 2次 MPOOL_MIN_CELL?

对齐到 MPOOL_MIN_CELL,整数除一次乘一次就把余数去掉了
10 楼 sunzixun 2009-12-02  
mp->max_cell_size = (mp->max_cell_size + MPOOL_MIN_CELL - 1) / MPOOL_MIN_CELL * MPOOL_MIN_CELL;  


为什么要 除以 2次 MPOOL_MIN_CELL?
9 楼 febird 2009-11-10  
iunknown 写道
我觉得可以整理一下,到 google code 上面去建立一个项目吧。


已经在 http://code.google.com/p/febird 上了,其中还有其它很多好东西

http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/c/mpool.c
http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/c/mpool.h

另有针对 std::allocator concept 的包装和 allocator to sallocator bridge,代码都很短:
http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/mpoolxx.h

febird.trb 使用 mpool的测试程序:
http://code.google.com/p/febird/source/browse/trunk/febird/vcproj/test_trb/test_trb_cxx.cpp
8 楼 febird 2009-11-10  
whaosoft 写道
快的不少 不过稳定吗? 在多多测试下~!
就lz的劳动成果 表示佩服 呵呵


目前很稳定,在febird.trb_tree 中的应用取得了非常好的效果,cache命中率比malloc/free/std::allocator 高很多——从测试程序的查找bench可以看出来!

{map|set|tab|strmap}但是,从设计之初,为了性能,我决定不支持多线程,因为一牵涉到线程,就太dirty了。

代码已有更新,在google code上了
http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/c/mpool.c
http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/c/mpool.h

另有针对 std::allocator concept 的包装和 allocator to sallocator bridge,代码都很短:
http://code.google.com/p/febird/source/browse/trunk/febird/src/febird/mpoolxx.h

febird.trb 使用 mpool的测试程序:
http://code.google.com/p/febird/source/browse/trunk/febird/vcproj/test_trb/test_trb_cxx.cpp
7 楼 whaosoft 2009-11-07  
快的不少 不过稳定吗? 在多多测试下~!
就lz的劳动成果 表示佩服 呵呵
6 楼 rrsy23 2009-11-06  
测试要充分哦;还是支持哈!
希望真的快一倍

但是不能简单测试开一倍

我做java的我写个简单的远程访问绝对比现在很多流行的快10倍

但是功能就,容错就

支持,但是要仔细
5 楼 iunknown 2009-11-06  
我觉得可以整理一下,到 google code 上面去建立一个项目吧。
4 楼 febird 2009-10-24  
linkerlin 写道
又一个轮子。

有好轮子可用,我不会去再发明。我需要一个C版的mpool,stlport.mpool不错,只可惜是C++版的。其它的:apache.apr.mpool, nginx.mpool,还有其它几个不知名的,都没有达到我期望的功能和性能。它们都没有体现剃刀原理。最小功能集,最大约束集,其结果就是最高性能级。
3 楼 febird 2009-10-24  
mathgl 写道
请问 怎么个高效法? 有benchmark么?

比 gcc.stl.pool_allocator 快一倍
2 楼 mathgl 2009-10-23  
请问 怎么个高效法? 有benchmark么?
1 楼 linkerlin 2009-10-23  
又一个轮子。

相关推荐

Global site tag (gtag.js) - Google Analytics