빌드의 병목 지점

C++ 프로젝트의 빌드 속도 개선하기 이론편/UnityBuild 편의 후속편이라고 할까? 특히 이론편에서 다룬 Incredibuild 라는 분산 빌드 제품에 대한 후기 같은 것을 쓰려 한다.

Incredibuild 라이선스를 구매하면 PC 한 대당 논리 프로세서 하나만 사용한다. 빌드에 참여하는 각 머신에 부하를 덜어주기 위한 배려라고 생각하면 오산! 현장에서는 쿼드 코어 내지는 핵사 코어를 사용하는데 논리 프로세를 둘 셋 쓴다고 크게 문제될 일도 없다. Incredibuild에는 빌드에 동원할 논리 프로세서 개수를 지정하는 옵션 자체가 없다. 알고 보면 논리 프로세서 개수의 제한은 수익 극대화를 위한 전략의 일환일 뿐이다. Xoreax 사는 Incredibuild Multiple CPU/Core Extension Package 라는 이름의 패키지를 추가 비용을 받고 판매한다.

이 패키지를 사용하면 무시무시한 광경을 보게 된다.

무려 30 여 개에 달하는 논리 프로세서가 빌드에 동원됐다. 물론 팀이 보유한 라이선스를 감안할 때 동시에 동원 가능한 논리 프로세서는 이보다 많은 50여 개 정도이긴 하다. SSD에서 Incredibuild를 동원해도 5분이 넘게 걸리던 빌드가 일반 HDD에서 5분 내에 빌드가 된다.

그런데 더 재미난 점이 있다. 그래프를 보면 단박에 알겠지만 대부분의 소스코드는 불과 2분 안에 빌드된다. 3분의 추가 시간은 순전히 소스 파일(.cpp) 두 개 때문에 소진된다(그래프 상에선 세 개지만 이 중 둘은 똑같은 파일이다). 이렇게 빌드가 걸리는 원인은 명확한데 파일 하나에 코드를 다 때려 박는 바람에 이 파일의 컴파일 시간이 전체 빌드 시간이 되어버렸기 때문이다. Visual Studio에는 이런 불균형을 시각적으로 보여주는 기능이 없기에 그동안 간과된 부분이다. 이제는 진부하기 짝이 없는 파레토 법칙이 여기서는 위력을 발휘한다. 불과 한 두 개의 파일 때문에 우리의 소중한 시간이 허공에 낭비되고 있다. 정량적인 측정과 대처가 얼마나 중요한지 다시금 일깨우는 대목이기도 하다.

문제의 파일 중 하나는 개선하기 매우 쉽다. 자료구조에 넣을 데이터 만 여 개를 하드 코딩한 것이 문제다. 데이터를 밖으로 빼서 실시간으로 읽으면 vector<string>::push_back 함수는 단 한번만 컴파일하고 끝날 것이다.

반면 다른 파일 하나는 꽤나 복잡한 설계 이슈가 끼어든다. 대부분의 응용프로그램에는 핵심이 되는 기능이 한 곳에 모이기 마련이다. 게임 클라이언트라면 애니메이션 처리부가 그런 곳일 가능성이 높다. 이런 곳에는 흔히 Manager 라는 이름의 클래스가 등장하고 각종 관련 기능(이를테면 팔, 다리 애니메이션 등)이 모여든다. 핵심 기능이기 때문에 코드가 복잡하고 빌드가 오래 걸린다. 그럴 싸하다. 이런 합리화를 거쳐 문제를 내버려두는 사람이 많지만 실은 중요 부분이기 때문에 설계에 더 주의를 기울여야 한다. 문제마다 특성이 다르므로 여기서 일괄적인 해법은 제시하지 않지만 컴파일러와 링커가 하는 일을 제대로 이해하고 C++의 언어적인 특징을 올바로 파악한다면 적절한 디자인 패턴을 적용하는 건 그리 어렵지 않다. 이렇게 레가시 코드가 한참 쌓이고 나면 문제 해결에 그만큼 시간과 노력이 들기 때문에 번거롭더라도 초기부터 문제를 잡아야 한다.

참고

우리 팀이 돈이 많아서 Incredibuild를 쓰는 게 아니다. 프로그래밍 외의 것도 신경 쓰면 팀 예산을 쓰지 않고도 훌륭한 소프트웨어와 도구를 사용할 기회는 많다. 안 될 거라 지레짐작하지 말고 일단 두드려봐라.

Advertisements

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu