개요

new/delete, malloc/free 는 매우 비싼 비용이 든다. syscall인 것도 문제고, 적절한 공간을 찾고 해제 후 다른 공간과 병합하는 복잡한 과정이 있기 때문이다.

이를 개선하자는 아이디어가 메모리 풀이다. 메모리 풀은 큰 사이즈를 한 번에 malloc한 뒤, 거기서 한 칸씩 나눠주는 식으로 구현한다.

내가 node라는 구조체를 자주 할당/해제 한다고 치면, node[1000] 짜리 배열을 한 번에 malloc한 뒤 할당 요청이 오면 한 칸씩 나눠주는 간단한 원리다. 실제 구현도 굉장히 간단하다.

성능 향상은?

기존 malloc/free에 비해 2배 ~ 100배 정도 성능이 향상된다. 구현과 사이즈에 따라 편차가 클 수 있다.

C 간단 구현 FixedMemoryPool

정말 간단하다. 보고 이해하자.

Assert를 모르는 사람을 위해

그 전에 잠깐. Assert (x == 0); 이러한 코드는 디버깅 빌드에서 x == 0 이 아니면 에러를 내주는 코드이다. 조건이 맞지 않으면 에러를 내주는 디버깅용 함수다.

어쨋든 코드를 보자 https://github.com/Ria9993/PlayGround/blob/main/Static Memory Pool/Static Memory Pool/main.c

Untitled

말한대로 max_size만큼의 큰 배열 하나와 free 상태인 칸들의 인덱스를 저장하는 index_table이 들어간다.

alloc과 free가 한 줄만에 끝나니 당연히 엄청 빠를 것이다. assert는 디버깅 빌드에서 버그를 잡기 위한 것이니 release 빌드에서는 포함되지 않음.

C++ Generic(Template) 구현

위에서 작성한 메모리 풀은 한 가지 자료형만 사용할 수 있으니 c++의 템플릿을 사용하여 모든 자료형에서 사용할 수 있도록 만들어보자.

필자는 ft_irc에서 메시지를 관리하기 위해 메모리 풀을 작성했다. 각 클라이언트가 각자의 버퍼를 가지고 있는 것이 아닌 모든 클라이언트가 메모리 버퍼를 공유하도록 해서 메모리 지역성을 높인다.

코드를 보자. https://github.com/Ria9993/IRC_server/blob/main/Source/Core/FixedMemoryPool.hpp