메모리 풀의 속도를 체크하는데...

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
hurguy
Posts: 53
Joined: 2002-03-04 09:00
Location: 12 장미단

메모리 풀의 속도를 체크하는데...

Post by hurguy »

Code: Select all

class test
{
public:	
	int a;
	test(void) : a(0)
	{
	}

	~test(void)
	{
	}

	static void *operator new(size_t size) {
		return pool.allocate(size);
	}
	static void operator delete(void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static void *operator new[](size_t size) {
		return pool.allocate(size);
	}
	static void operator delete[](void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static stl::allocator<test> pool;
};

allocator<test> test::pool;
Effective C++ 항목 10처럼 해서 stl::allocator를 이용해 메모리 풀에 new, delete, new [], delete []등 속도 체크를 했습니다. 이 풀을 동료분이 만든 custompool class로도 해보고, boost님의 fast_pool_allocator로 바꾸어서 해보고, 그냥 heap메모리 할당등 테스트를 했는데 boost님<stl님<동료님<heap님 즉 heap이 가장 빨랐습니다. 그런데 제가 boost::fast_pool_allocator랑 stl::allocator를 잘못 사용한건지 custompool보다 수십배에서 수백배나 느렸는데 아무리 차이가 나도 그정도까지는 아닐꺼라고 생각해서 질문을 올립니다. 제 코드나 아니면 제가 allocator사용법에 대해 잘못 이해하고 있는건지 답변부탁드립니다.
어둠은 어둠으로 맞서라 그러면 재밌는 일이 생긴다.
비회원

Re: 메모리 풀의 속도를 체크하는데...

Post by 비회원 »

hurguy wrote:

Code: Select all

class test
{
public:	
	int a;
	test(void) : a(0)
	{
	}

	~test(void)
	{
	}

	static void *operator new(size_t size) {
		return pool.allocate(size);
	}
	static void operator delete(void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static void *operator new[](size_t size) {
		return pool.allocate(size);
	}
	static void operator delete[](void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static stl::allocator<test> pool;
};

allocator<test> test::pool;
Effective C++ 항목 10처럼 해서 stl::allocator를 이용해 메모리 풀에 new, delete, new [], delete []등 속도 체크를 했습니다. 이 풀을 동료분이 만든 custompool class로도 해보고, boost님의 fast_pool_allocator로 바꾸어서 해보고, 그냥 heap메모리 할당등 테스트를 했는데 boost님<stl님<동료님<heap님 즉 heap이 가장 빨랐습니다. 그런데 제가 boost::fast_pool_allocator랑 stl::allocator를 잘못 사용한건지 custompool보다 수십배에서 수백배나 느렸는데 아무리 차이가 나도 그정도까지는 아닐꺼라고 생각해서 질문을 올립니다. 제 코드나 아니면 제가 allocator사용법에 대해 잘못 이해하고 있는건지 답변부탁드립니다.
전 릴리즈 모드에서 힙 메모리보다 10배정도 빠르던데요 [부스트 메모리풀이..]
비회원

제가 테스트한 소스입니다.

Post by 비회원 »

Code: Select all

#include <stdio.h>
#include <time.h>
#include <conio.h>

#define HEAP_ALLOC
//#define BOOST_ALLOC
//#define STL_ALLOC

#ifdef STL_ALLOC
#include <xmemory>
using std::allocator;
#endif

#ifdef BOOST_ALLOC
#include "boost/pool/pool_alloc.hpp"
using boost::pool_allocator;
using boost::fast_pool_allocator;
#endif

class test
{
public:	
	__int32 a;
	test(void)
	{
	}

	~test(void)
	{
	}
#ifdef HEAP_ALLOC
};
#endif
#ifdef STL_ALLOC
	static void *operator new(size_t size) {
		return pool.allocate(size);
	}
	static void operator delete(void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static void *operator new[](size_t size) {
		return pool.allocate(size);
	}
	static void operator delete[](void *p, size_t size) {
		pool.deallocate((test *)p, size);
	}
	static allocator<test> pool;
};

allocator<test> test::pool;
#endif
#ifdef BOOST_ALLOC
static void *operator new(size_t size) {
	return pool.allocate(size);
}
static void operator delete(void *p, size_t size) {
	pool.deallocate((test *)p, size);
}
static void *operator new[](size_t size) {
	return pool.allocate(size);
}
static void operator delete[](void *p, size_t size) {
	pool.deallocate((test *)p, size);
}
static pool_allocator<test> pool;
};

pool_allocator<test> test::pool;
#endif

#define TEST_NUM 10000

int _tmain(int argc, _TCHAR* argv[])
{
	test	*gp,*fp;
	test	*s1,*s2,*s3, *s4;
	test	*k1,*k2,*k3, *k4;
	__int32 j, chk1,chk2;
	bool chk = false;

	chk1 = clock();	

	for (j = 0; j < TEST_NUM; j++)
	{
		gp = new test[35+(j>>1)];
		fp = new test[105+(j>>4)];

		delete[] fp;

		s1 = new test[10];
		s2 = new test[15];
		s3 = new test[27];
		s4 = new test[49];
		delete[] s2;

		k1 = new test[11];
		k2 = new test[50];
		k3 = new test[100];
		k4 = new test[82];

		s2 = new test[33];

		if(j%1000 == 0)
		{
			printf("--------------------- j : %d\n",j);
		}
		delete[] s1;
		delete[] s2;
		delete[] s3;
		delete[] s4;
		delete[] k1;
		delete[] k2;
		delete[] k3;
		delete[] k4;
		delete[] gp;

	}
	printf("--------------------- j : %d\n",j);

	chk2 = clock();	
	printf("\n------------------------------- 1\n");
	printf("chk1 : %d, chk2 : %d\n",chk1,chk2);
	printf(" chk2 - chk1  = %d\n",chk2 - chk1);
	getch();

	return 0;
}
다시 테스트 해보니 힙과는 STL은 비슷하게 나오는데 역시나 BOOST님은 엄청 느립니다.
엉클뻐커
Posts: 194
Joined: 2001-10-22 09:00
Location: 30대후반 고졸 백수

Post by 엉클뻐커 »

boost :: pool 님은 고정크기의 블럭들을 할당할때 빨라지라고 만들어진 분이시라서.
무작위적인 크기의 배열을 할당한다면 느린게 당연하십니다.
list나 map, set 같은 컨테이너에 사용해주시면 STL의 기본 할당자님보다 월등한 속도를 내주실거여요.
비회원

정확히 어떨때 사용하는건지

Post by 비회원 »

엉클뻐커 wrote:boost :: pool 님은 고정크기의 블럭들을 할당할때 빨라지라고 만들어진 분이시라서.
고정크기 블럭들을 할당 하때라고 하니 딱 머리속에 그려지지 않아서요. boost::pool을 이용하는 코드라던가 자세한 설명 부탁드립니다.
list나 map, set 같은 컨테이너에 사용해주시면 STL의 기본 할당자님보다 월등한 속도를 내주실거여요.
위의 커테이너을 제 소스에 적용한다는 어떻게 되는지 내공부족으로 이해하기가 어렵네요. 대략을 코드를 적어 주시면 감사하겠습니다.
엉클뻐커
Posts: 194
Joined: 2001-10-22 09:00
Location: 30대후반 고졸 백수

Re: 정확히 어떨때 사용하는건지

Post by 엉클뻐커 »

고정크기 라고 하니 전달이 잘 안된 모양이군요.

boost :: pool 은 노드기반 컨테이너의 노드처럼 동일한 크기의 객체를 빈번히 할당해제할때 유용한 것입니다.

std :: list <타입, boost::fast_pool_allocator<타입> > 와
std :: list <타입 > 에 객체를 넣고 빼고를 반복해 보세요.

튜토리얼이나 레퍼런스를 원하시면 jacking 님 홈페이지에
http://jacking75.cafe24.com/
http://jacking75.cafe24.com/Boost/Pool/conception.htm
boost 문서의 상당량을 번역해 놓으셨습니다.
free108
Posts: 56
Joined: 2001-12-28 09:00

Post by free108 »

저도 메모리 풀에 눈길이가서 boost::pool 을 가지고 이것 저것 점검을 해보았습니다.

성능 비교시에 보니 그냥 heap 에 할당하는 것과 비교하여 그다지 성능 향상은 없고
가끔은 오히려 느린 현상이 보이더군요. 그래서 이것 저것 살펴보던 도중 boost의 pool 중에서
singleton_pool ( pool_allocator, fast_pool_allocator 도 내부적으로 singleton_pool 을 사용하고 있음. ) 이 녀석이
Thread-Safety 특성이 있는 관계로 성능 저하가 있는 것을 발견하였습니다.

그래서 아래와 같이 boost::details::pool::null_mutex 로 바꿔줘서 Mutex 관련 부하를 제거하니 확실히 성능이 향상이 있군요.

Code: Select all

std::list<int, boost::fast_pool_allocator<test2_c, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex> > mylist;

struct test2_c_tag { };
typedef boost::singleton_pool<test2_c_tag, sizeof(test2_c), boost::default_user_allocator_new_delete, boost::details::pool::null_mutex> test2_c_pool;
만약 Thread-Safety 가 요구되지 않는 곳에서는 boost::details::pool::default_mutex 를 그대로 사용하지 않고,
boost::details::pool::null_mutex 로 설정하는 것이 확실한 성능 향상에 도움이 될 듯 합니다.
ascalon
Posts: 152
Joined: 2005-05-27 09:47
Contact:

멀티스레드 메모리 테스트 프로그램

Post by ascalon »

이전에 윈도우즈의 LFH와 Hoard의 성능을 비교하려고 만들어 본 테스트 프로그램이 있어 공개합니다. 결과가 Hoard의 성능이 아주 저조하게 나왔습니다. 혹시 윈도우즈용 Hoard에 문제가 있거나 테스트 환경에 문제가 있을지도 모르겠습니다. 소스코드도 함께 넣었으니 궁금하신 분은 참고 하시고, 문제를 발견하면 알려주시면 감사하겠습니다.

http://devnote.net/wiki/index.php/Windows_Heap_Memory
Locked