C++ PIMPL 패턴.. 별로임 -_-;

김포프 2013-05-21

생각해보니 개인적으로 PIMPL 패턴을 직접 구현해본 적이 없다. 이런 패턴이 있다는걸 예전에 읽어본 적은 있지만.. 그냥 '그닥 쓰고 싶은 생각이 안나는 놈?' 정도로 생각했다고 할까…

음 근데.. 지금 다루고 있는 코드베이스 안에는 PIMPL 패턴이 아주 넘친다… 그래서 사용해본 뒤 소감이 어떻냐고? 안.좋.다. 게임 프로그래밍에서 이 패턴을 씀으로써 얻는 장점이 별로 없다고 생각한다. PIMPL 패턴의 장점이 뭘까? 다음 두 가지 장점 정도가 아닐까?

  1. API 설계와 구현의 확연한 구분: 소프트웨어 아키텍트 마스터가 API를 멋지게 설계해두면 쫄개 프로그래머/코드 몽키들을 와라락 달려들어 잘 숨겨진 파일안에 구현을 함
  2. 헤더파일간의 의존성(dependency)이 적음 = 컴파일 시간이 빠름

일단 장점 1번이 게임 프로그래밍 업계에서 큰 의미가 있다고 생각하지 않는다. 어느 엔터테인먼트 업계에서도 그러듯이 게임의 요구사항은 끊임없이 변하며 그에따라 API도 수도없이 바뀐다. 즉, 마스터가 API를 멋지게 설계하는 일 자체가 별로 없단 이야기. 그리고 다른 프로그래머들로부터 구현파일을 숨긴다는거 자체도… 좀 웃기지 않나? 게임 프로그래머들은 전체 소스코드를 보는 걸 좋아한다. 라이브러리를 만들어서 파는 3rd party업체가 아닌이상… 정말 별 의미가 없음…

게임 프로그래머들이 PIMPL 패턴을 왜 쓰는 주 이유는 사실 2번이라고 생각한다. C++ 의 컴파일 속도는 매우 구려요 -_-;;; 하지만 PIMPL 패턴 보다 컴파일 속도를 향상시킬 수 있는 다른 방법이 존재한다. 물론 조홀라 비싼 incredibuild를 말하는 건 아니다. 여태까지 써본 방법중에 가장 빠른 건 이미 10년전부터 널리 애용되고 있는 유니티 빌드였다.. 물론 공짜 -_-v… 이에 대한 제대로된 한국말 설명은 다음의 슬라이드를 참고.

따라서 PIMPL의 장점이 그닥 중요하가 와닿지 않는 반면.. 단점은 아주 절절히 느껴지는게 문제….

  1. 코드 읽기가 더 귀찮아진다. 파일 여러개를 뛰어다녀야만 겨우 구현코드를 볼 수 있다는 단점….매조키스트 아닌 다음에야 이걸 좋아할리가…
  2. 듬성듬성한 메모리 할당: pimpl 개체를 만들기 위해 따로 new를 호출해줘야 한다. 메모리 파편화, cache 관리 등의 이유로 개인적으로 클래스의 모든 멤버가 한번에 메모리할당되는 걸 좋아하고, 그 외에도 어떤 개체의 크기를 쉽게 알아오기에도 한번에 할당되는게 좋다.
  3. 추가적인 포인터 참조 연산 = 아주 조금 더 느림…. 이정도 포인터 점프 한번 더 하는게 성능에 아주 큰 영향을 미치지는 않는다. 하지만 엔진쪽 프로그래밍 하는 사람으로써 이런 필요없는 포인터연산이 성능을 10프로 이상 떨어뜨리는 걸 수도없이 봤기에… 매우 까탈스러울수밖에 없다… 아마 실제로 이 포인터 참조에 걸리는건 CPU 사이클 4사이클 정도일 테지만… pimpl 개체의 메모리 위치가 떨어져 있을 수도 있으니 cache 관리까지 들어가면 더 느릴수 있다는 것…. 물론 메모리 할당 순서를 손수 잘 컨트롤 해주면 이런 문제를 피할수도 있겠지만, pimpl 패턴의 장점이 크게 없는 이상 왜 이런 쓸데없는 짓을 해야하나 생각까지 든다.

결론! 핌플 맘에 안듬.. -_- 아니면 내가 뭔가 놓치고 있는게 있나?

참고로 영어로 pimple은 뾰드락지를 말함 -_- 이런 거…

pimple