`
febird
  • 浏览: 256438 次
  • 性别: 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  
又一个轮子。

相关推荐

    C++内存池完整代码memory_pool.zip

    在"memory_pool.zip"这个压缩包中,我们可以预期包含了一个实现C++内存池的源码项目。"Makefile"是用于编译和构建项目的配置文件,它定义了如何将源代码文件编译成可执行程序或库。我们可以通过运行`make`命令来编译...

    Super-memory-pool.rar_super

    而“Super memory pool”这个文件名暗示了一个或多个源代码文件,其中可能包含了内存池的主要实现逻辑,如内存块的组织和管理、内存分配与释放的接口等。最后,“TestPrj.txt”很可能是一个测试项目说明,它能帮助...

    C++ Memory Pool for Apache 2-开源

    内存池(Memory Pool)是一种优化内存分配策略的技术,它在Apache服务器中扮演着至关重要的角色。本文将深入探讨如何在C++编程环境中,利用内存池技术来提升Apache模块的性能。 内存池的基本原理是预先一次性分配一...

    Tomcat设置服务启动参数

    为了确保Tomcat能够高效稳定地运行,合理配置其启动参数至关重要,尤其是与内存相关的参数。本文将详细介绍如何在Tomcat中设置启动参数,并探讨这些参数的具体含义及其最佳实践。 #### 二、Tomcat启动参数概述 在...

    C#高效编程改进C#代码的50个行之有效的办法( 第2版) 中文版

    44. **了解并使用Memory Pool优化内存分配**:内存池可以提高内存分配和释放的效率。 45. **掌握并运用.NET框架的缓存策略**:如MemoryCache,用于在内存中缓存数据,提高性能。 46. **理解并使用Type....

    memory_pool

    在`memory_pool-main`这个项目中,我们可以推测它可能是一个简单的内存池实现,包含一个主函数`main`来演示如何使用内存池进行内存分配和释放。源代码可能会包含一个内存池类,提供分配、释放和初始化等方法。通过...

    memory_assign_and_management.doc

    内存分配和管理是编程中至...总的来说,理解C语言中的内存分配和管理,以及如何利用Memory Pool来优化内存使用,是编写高效、健壮程序的关键。在实际开发中,合理使用这些工具和策略可以极大地提升程序的性能和稳定性。

    MemoryPool 实用的例子程序

    `MemPoolMgr.cpp` 和 `MemPool.cpp` 可能包含了内存池的实现代码,`MemPoolMgr.h` 和 `MemPool.h` 是对应的头文件,声明了类的接口和必要的数据结构。在这些源文件中,我们可能会看到以下关键点: - 数据结构:如...

    ib_fmr_pool.rar_space

    标题中的"ib_fmr_pool.rar_space"暗示了我们讨论的主题是关于Linux内核的一个用户空间算法接口,特别是与IBM Foreign Memory Region(FMR)池相关的实现。在Linux系统中,Foreign Memory Regions允许用户空间程序...

    内存池源代码--在给定buffer上实现内存管理机制

    在压缩包文件"memory pool"中,可能包含了实现内存池的源代码示例,包括内存池结构体定义、内存分配和释放函数,以及相关管理算法的实现。通过分析和学习这些代码,可以更深入地理解内存池的工作机制,并在实际项目...

    tmem.zip_memory

    这个“tmem.zip_memory”压缩包包含的“tmem.c”源代码文件很可能是实现这种内存管理功能的一个关键部分。 Xen是一款开源的类型一(bare-metal)hypervisor,它允许在一个物理主机上同时运行多个操作系统实例,即...

    Memory Pools V1.2

    内存池(Memory Pool)是一种内存管理技术,常用于优化系统资源的分配与释放,提高程序运行效率。在软件开发中,尤其是系统级编程和嵌入式领域,内存池扮演着重要角色。Memory Pools V1.2 可能是这个内存池管理库的...

    linux内存池代码实例

    在Linux系统中,内存管理是操作系统的核心组成部分,内存池(Memory Pool)是一种高效的内存分配策略。内存池通过预先分配一大块连续的内存区域,并对其进行分割和管理,为应用程序提供内存分配服务,以此来提高内存...

    Apache源代码分析

    Apache的内存管理基于内存池(Memory Pool)的概念。内存池是一种预先分配大块内存,并从中动态分配小块内存的方法,旨在减少频繁调用系统分配器(如malloc)的开销。这不仅提高了内存分配效率,也便于内存碎片管理...

    demo_of_xerces-c++_MemoryManagement

    Xerces-C++内存管理的核心是内存池(Memory Pool)机制。内存池是一种优化内存分配和释放的技术,它预先分配一大块连续的内存空间,并以固定大小的小块分发给请求者,从而避免了频繁的系统调用,提高了内存分配和...

    C语言实现完整功能的内存池

    4. **内存池初始化和销毁**:`init_memory_pool`用于在程序启动时预分配内存,`destroy_memory_pool`在程序结束时释放所有内存。 5. **内存碎片问题**:为了达到“内存0碎片”的标准,内存池需要有策略地管理内存,...

    nginx内存池代码封装

    其中,内存池(Memory Pool)是一种特殊的内存分配方式,它优化了内存的分配和释放过程,减少了碎片,并且在高并发环境下提供了更好的性能。下面我们将深入探讨Nginx的内存池实现及其代码封装。 1. **内存池概念** ...

    固定块内存池c语言实现

    固定块内存池(Fixed Block Memory Pool)是一种优化内存分配的策略,它预先分配一大块内存,并将其分割成固定大小的小块,用于满足程序中对特定大小内存的需求。这种方法能够提高内存分配效率,减少碎片,并提供更...

    13、线程池ForkJoinPool实战及其工作原理分析(1).pdf

    - **实现方式**: 可以利用`ForkJoinPool`来实现多线程版本的归并排序。 - **代码示例**: ```java public class ParallelMergeSort { private final int[] arrayToSort; private final int threshold; public ...

    Apache源代码剖析

    在Apache及其依赖库APR(Apache Portable Runtime)中,内存池(Memory Pool)的概念被广泛使用。本文将深入探讨Apache内存池的工作原理及其在实际应用中的作用。 #### 二、内存池概述 在C语言编程中,内存管理...

Global site tag (gtag.js) - Google Analytics