본문 바로가기

Library/C/C++

메모리 풀 형식의 할당기 제작

C++에서 기본으로 제공하는 힙 할당자인 new와 delete는 그 성능이 시원치 않다. 일반적인 경우, 운영체제에서 힙에 대해서 메모리 풀을 구현하고 있기 때문에 일정 크기 이하에 대해서는 크게 체감할 수 있는 부분은 아니지만, 이렇게 제공되는 메모리 풀은 일반적인 목적에 맞춰 제작된 풀이므로, 그렇게 성능이 처지는 것도, 그렇게 성능이 좋은 것도 아니다. 물론, 이것은 new와 delete 자체가 조악하다는 것이 아니라, 만들고자 하는 프로그램에서 요청되는 메모리 할당 / 해제 유형에 new와 delete가 잘 맞지 않을 수도 있다는 뜻이다. 따라서, 프로그램의 메모리 요청 유형에 적합한 할당기를 만들 필요성이 있는데..

할당은 어떻게 하더라도 사실 그렇게까지 차이가 나지 않는 것 같은데, 문제는 메모리 해제이다. 미리 커다란 크기의 힙을 할당 받은 뒤, 요청되는 크기에 따라 이 힙을 적절하게 분류하고, 요청이 올 때마다 여기서 블럭을 할당한다. 할당은 간단한 캐시를 도입하면 큰 차이가 나지 않지만, 해제는 해제를 원하는 블럭의 포인터가 주어졌을 때, 이 풀에서 어떤 방식으로 탐색을 해야 빠르게 해제할 블럭의 주소를 알아낼 수 있는가가 문제가 된다.

가장 최악은 선형 시간이 소모되는 경우인데, 이것은 블럭 집합을 모두 탐색하면서 해제할 포인터가 속한 블럭을 조사해보는 방법이다. 캐시를 도입한다고 하더라도, 캐시는 자체적으로 수행 시간이 존재하기 떄문에 선형적으로 이루어지는 해제 요청에는 오히려 더 안좋은 성능을 보일 수 있다.

즉, 트레이드 오프 사항은 이것이다. 빠른 할당 / 해제를 위해서는 캐시와 같은 보조 장치가 필요하지만, 이들을 사용함으로써 얻어지는 이점과, 이러한 보조 장치가 실패했을 때 잃게되는 비용 사이에서, 어떻게 균형을 잡아야 할 것인가? 또, 이러한 보조 설비를 사용하기 위해서는 기본적인 할당, 해제에 추가적인 루틴이 들어가야 하는데, 어느 정도 수준에서 이들을 통제해야 하는가 따위이다.