본문 바로가기

Library/C/C++

Improved Angra

boost::pool, Loki::SmallObject와 같은 메모리풀은 4 바이트 미만의 데이터에 대해서도 메모리 할당을 할 수 있다. 특히, boost::pool의 SSS(Simple Segregated Storage)는 4 바이트 미만 단위의 메모리풀을 구성하더라도 독특한 메모리 정렬 기법을 사용하기 때문에 성능상의 손실이 그다지 크지 않지만, Loki::SmallObject는 성능 손실이 매우 크다. 과연 4 바이트 미만의 메모리 할당 능력이 다른 모든 것을 희생해야 할 만큼 중요한 것일까?

Alexandrescu가 지적했던 것처럼, 최근의 프로그래밍 기법들이 작은 크기의 개체를 적극 활용하고 있다. 그러나, 사실 4 바이트 미만의 데이터를 다룰 일은 거의 없다. 이것은 4 바이트 미만의 데이터로 클래스가 구성되더라도 패딩(padding) 때문에 각 머신의 비트수에 맞게 패킹되기 때문이다. 단순히 배열로서의 성격이 강한 데이터에 대해 메모리풀을 구성하는 경우라면 모르겠지만, 개체로서의 성격이 두드러지는 4 바이트 미만의 데이터를 그 크기 그대로 할당하는 것은 성능면에서 매우 불이익이 크다. 즉, 현실적인 관점에서, 메모리풀 구성의 최소 사이즈로 4 바이트 이상을 요구하는 것은 큰 문제가 되지 않는다. 예를 들어, ACE가 제공하는 메모리 할당기는 4 바이트 이상의 데이터에 대해서만 풀을 적용할 수 있는 반면, 그야말로 엄청난 성능을 보여준다.

Loki::SmallObject의 가장 큰 문제는 바로 이 부분이며, 블로그지기의 Angra 메모리풀이 boost::pool보다 성능면에서 처지는 가장 중요한 이유 중 하나도 메모리 정렬 문제와 관련된 최소 요구 바이트 크기 때문이었다. 이것을 개선하여 최소 4 바이트 이상의 데이터에 대해서만 메모리풀을 구성하도록 고쳐보았다. 결과는 상당히 만족할만한 수준이었다. 순차 할당 / 해제 작업에서는 거의 모든 크기의 메모리 블록에 대해 이전 버전의 Angra에 비해 크게 개선된 성능을 보여주었으며, boost::pool보다 근소하게 나은 성능을 보여주었다. 물론, 이것은 boost::pool 보다 모든 면에서 우월하다는 뜻은 아니다. 아직은 단지 순차 할당 / 해제 작업에 대해서만 테스트를 한 것이고, 보다 중요한 무작위 해제에서의 성능은 측정하지 않았다. 그러나, 이 결과는 충분히 긍정적이다. 특히, 단위 전략으로 구성된 Angra의 특성을 살려 고전적인 Loki::SmallObject의 Chunk 방식과 새롭게 개선된 방식을 선택 사항으로 넘겨준다면 사용자는 각자의 필요에 맞춰 단위 전략을 선택할 수 있을 것이다. 또, Loki::SmallObject는 Chunk의 할당 가능한 메모리 블럭 수가 사실상 255개로 제한되는데, 위에서 언급했던 4 바이트 제한 사항을 둔다면 이 인자 역시 좀 더 능동적으로 필요에 맞추어 조절할 수 있다.

개선된 Angra는 Loki::SmallObject가 최소 메모리 블럭 크기만 결정할 수 있는 것과 달리, 좀 더 풍부한 인자에 의해 맞춤식 메모리풀을 형성할 수 있다. 갈무리 화면의 테스트 코드는 참고 자료에 첨부했다.






여담으로, boost::pool의 SSS는 정말 탁월한 메모리풀 자료형이다. boost::pool을 설계한 거장들은, 이와 같은 모든 문제를 고려했다. SSS는 메모리 정렬 문제를 해결하면서도 공간적인 면에서 오버헤드를 최소화했다. Angra가 할당 / 해제 성능이 boost::pool보다 조금 더 나을지 몰라도, 메모리풀의 메모리 공간 오버헤드까지 감안하면 SSS의 효율성을 따라가지 못한다. 결국 SSS 구조와 같은 결론에 도달했는가? 그렇다면 축하한다. 당신 또한 거장들의 세계에 입문한 것이다.





Appendix