jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다. 3ds Max를 사용해서 게임용 3D 캐릭터를 셋업하는 방법
이를 위해 오랜 실무를 경험해 온 저자의 고급 노하우들이 공개
위 내용은 GameDevForever의 저자분들의 홍보를 위하여 운영진 자체적으로 올린 광고이며 일체의 수익이 없습니다.(밥좀사줘요~)
Posted by 김포프

생각해보니 개인적으로 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은 뾰드락지를 말함 -_- 이런거...





댓글을 달아 주세요

  1. 제레미 2013.06.03 10:48 신고  댓글주소  수정/삭제  댓글쓰기

    개인적으로는 Pimpl 패턴을 자주 사용하려고 하는 편이지만, 언급하진 단점에 대해서는 동의합니다.

    제가 생각하는 Pimpl 패턴의 장점 한가지만 추가하자면, "설계가 잘못된 방향으로 가는 것을 방지해준다" 입니다. 라이브 프로젝트이거나, 일정과 시간에 시달리다 보면 퍼블릭으로 멤버변수를 선언한다거나 getter setter 를 남발한다거나 영혼을 팔게 되는 경우가 종종있는데, 해당 클래스가 Pimpl 로 작성되어 있다면, 처음부터 땜빵코드를 넣지 않거나 나중에라도 수정하게 되었습니다.

    물론 처음부터 잘 하는 사람에게는 쓸모없는 장점입니다만..

    • Favicon of http://gamedevforever.com 김포프 2013.06.04 15:49 신고  댓글주소  수정/삭제

      영혼을 팔 일이 아예 없을정도로 잘하는 프로그래머가 존재하진 않을거 같은데요.... ㅎㅎ

      pimpl로 만들더라도 당장 급하면 pimpl에 땜빵함수를 만들고 pimpl을 포함하는 API에 떔빵함수를 만들어 그 함수를 그냥 호출해주는 경우도 많이 봤습니다 ㅎㅎ.

      사실 이건 pimpl의 문제가 아니라.. 이런 땜빵 함수를 만들경우 이걸 고치라는 task를 백로그에 추가해놓고 급한 불 끈뒤에 제대로 다시 고치는 자세/습관을 가지는게 더 좋지 않나 생각합니다.

    • Favicon of http://gamedevforever.com 끼로 2013.06.04 18:54 신고  댓글주소  수정/삭제

      추가로 코드 리뷰가 정착된 팀에서도 마찬가지로 이런 문제는 많이 해소할 수 있다고 생각합니다. 저희 파트의 경우엔 리뷰어가 리뷰하지 않은 코드는 svn에 올리지 못하는 규정이 있는데 그래서 리뷰어가 좀 빡세긴 하지만 여러 문제를 빠르게 잡을 수 있는 효과가 있지요..

  2. Favicon of http://bluekms21.blog.me 크로스 2013.06.05 14:41 신고  댓글주소  수정/삭제  댓글쓰기

    저는 코드 오픈도 사랑하지만 코드 캡슐화도 사랑합니다.
    대신 캡슐화를 할 클래스를 디자인하는 사람은 (최초 라이브러리 설계자) 그 클래스를 보증해야 하죠.

    pimple패턴은 그런점에서 좋기는 개뿔
    소스코드가 열려있는 경우 소스코드를 읽으려는 사람은 왠지모를 F12를 두세번 눌러 내부에서 구현을 봐야하고
    소스코드가 닫혀있는 경우 계속 new로 할당을 해줘야 해서 (별도의 메모리 할당자를 사용하지 않는 한) 메모리 단편화라던가 하는 문제가 생기겠습니다만
    구글 안드로이드 API들은 버전업할때마다 빌드조차 안되니까 좀 저런걸로 구현해줬으면 하기도 하고...
    뭔가 복잡한 심정입니다.. (먼산)

    ...그 대단하신 구글님이 자꾸 설계변경해서 API 구버전 호환 안되게 하는걸 보면
    pimpl 패턴은 전제부터가 불가능인건가.. 싶기도 하고요;;



티스토리 툴바