요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업들의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

C/C++ 대규모 프로젝트에서 빌드 속도를 올려보자

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업들의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?

 

이번 글은 ‘전 세계 사람들에게 즐거움을 선사하자’는 비전을 바탕으로 게임을 만들고 있는 ‘넷마블’의 기술분석팀 이야기입니다. 상용툴을 사용하지 않고 빌드 속도를 올릴 방법을 찾아간 여정을 공유합니다.

 

안녕하세요, 넷마블 기술분석팀 김범진입니다.

커피 한잔을 앞에 두고 비주얼 스튜디오 2019에서 ‘F7’키나 ‘Ctrl + Alt + F7’키를 누른 후, 올라가는 프로그레스바를 무심히 바라보신 기억이 있으신 분들께 이 글을 올립니다.

 

솔루션 빌드
‘F7’키나 ‘Ctrl + Alt + F7’키를 눌러서 빌드 실행 (출처 : 본인)

 

현업 프로젝트에서 빌드하는 코드는 짧아도 몇만 줄, 길게는 몇백만 줄이 되기도 합니다. 당연히 코드가 늘어날수록 빌드 속도는 더디어지고, 이 시간이 누적되면 테스트 시간을 확보하지 못하는 문제까지 이어지기도 합니다.

 

C와 C++ 대규모 프로젝트에서 빌드 속도를 올릴 방법이 있지 않을까요?

 

참고로, 언리얼 엔진(Unreal Engine)에서는 공식 문서에서 ‘bUseUnityBuild’ 옵션을 볼 수 있습니다. 이 글에서는 이 옵션에 대한 내용은 다루지 않습니다. 만약 언리얼 엔진에서 ‘bUseUnityBuild’ 옵션을 사용하실 분들께선 충분히 검토 후 사용하시길 당부드립니다.

 

 

상용 툴

상용 툴 중에는 인크레디빌드(Incredibuild)가 있습니다. 인크레디빌드는 그리드 컴퓨팅 방식을 활용해 빌드 속도를 높여주는 툴입니다. 간단히 찾아봤더니, 엔터프라이즈 라이선스 비용이 상당했었습니다. 제품 소개 상으로는 80~90%가량 빌드 시간을 단축해준다고 하니, 비용대비 효과는 충분할 수 있습니다.

 

 

유니티 빌드(Unity Build)

상용 툴 이외에는 어떤 방법이 있을지, 효율적으로 빌드속도를 개선할 방법은 없을지 궁금해서 더 찾아보던 중 눈에 들어온 방법이 유니티 빌드(Unity Build)였습니다. 여기서 이야기하는 ‘유니티 빌드(Unity Build)’ 방법은 지금 우리가 흔히 떠올리는 유니티(Unity) 게임 엔진 이야기가 아닙니다. 개발 아이디어의 한 종류입니다.

 

NDC 2010에서 ‘UnityBuild로 빌드타임 반토막 내기’라는 발표가 있었습니다. 
(발표 내용 자체는 원문 링크를 참고해주세요.)

참고링크1: 위키피디아

참고링크2: Unity Builds

 

 

유니티 빌드에서 받은 영감

컴파일 단계

빌드 속도에 영향을 주는 요소를 살펴보려면, 컴파일 단계를 먼저 이해해야 합니다.

 

컴파일 단계
컴파일 단계 (출처:knowinfo.com)

 

컴파일 단계는 크게 4단계로 구분할 수 있습니다.

 

1단계 – 전처리(Preprocessing)

전처리(Preprocessing) 단계는 매크로(#define), 헤더 (#include), 메타 소스 생성(template) 등을 분석해 소스를 텍스트(Text)화하는 단계입니다.
 

2단계 – 컴파일(Compilation)

컴파일(Compilation) 단계는 전처리 단계에서 텍스트화 된 소스와 cpp 파일에 들어 있는 소스를 어셈블리 언어로 번역하는 단계입니다.
 

3단계 – 어셈블(Assemble)

어셈블(Assemble) 단계는 컴파일 단계에서 번역한 어셈블리 언어를 기계어(obj)로 변경하는 단계입니다. 완전히 기계어로 바꿔주는 부분이라고 생각하시면 됩니다.
 

4단계 – 링크(Linking)

링크(Linking) 단계는 어셈블 단계에서 생성한 obj와 라이브러리를 묶어, 실행 파일 또는 라이브러리로 만드는 단계입니다.

 

 

아이디어

유니티 빌드에서는 무의미한 코드 라인을 제거하고 헤더 파일을 정리하면서, 컴파일러 입력량과 참조 파일 개수를 줄였습니다. 그리고 그렇게 줄인 만큼 전체 빌드 속도가 향상됐었습니다.

 

유니티 빌드에서 했던 내용 중, “컴파일 입력량 줄이기”에 집중해보기로 했습니다. 컴파일 단계의 시작점인 전처리 단계에서 산출되는 텍스트양을 줄일 수 있다면, 컴파일 작업도 동시에 줄일 수 있을 테니까요.

 

 

전처리 산출물 테스트

이제 아이디어를 실행해 보면서, 효과를 확인해보겠습니다.

 

전처리 테스트
테스트 소스 (출처 : 본인)

 

먼저 테스트 파일 3개를 준비해, 모두 ‘#include 를 추가했습니다. (딱히 어떤 특징적이라거나 기능적인 요소가 있는 참조는 아닙니다.) 전처리만 실행한 결과를 보기 위해 ‘cl.exe’를 ‘/E’ 옵션으로 실행했습니다.

 

$ cl.exe /E a.cpp > precompile_a.txt$ cl.exe /E b.cpp > precompile_b.txt$ cl.exe /E main.cpp > precompile_main.txt

 

cl 실행
cl.exe /E 실행 (출처 : 본인)

 

파일 용량
전처리 이전과 이후 파일 용량 (출처 : 본인)

 

전처리 이전에는 362바이트(53+85+53+86+85)였으나, 전처리 이후에는 3,423,451바이트(919650+919651+1584150)로 약 3MB 정도 늘어났습니다. 전처리로 무엇이 바뀌었는지 보기 위해 파일 내용을 열어봤습니다.

 

산출물 분석
산출물 내용 분석 (출처 : 본인)

 

전처리 전에 7줄이었던 ‘a.cpp’ 파일과 b.cpp’ 파일은 약 4만 줄 정도로 늘었고, 전처리 전에 9줄이었던 ‘main.cpp’ 파일은 약 6.7만 줄이 될 만큼 늘었습니다. 간단히 늘어난 내용을 훑어보니, 공백도 많고 중복된 소스도 많아 보였습니다. 이후 진행할 컴파일 단계에서 공백은 총 컴파일 시간에 영향을 주지 않으리라 보이지만, 중복된 소스는 생성된 수만큼 영향을 줄 우려가 있어 보입니다.

 

cpp 파일 수에 따라 중복이 생길 것이라 예상되므로, 중복 소스 생성을 줄일 수 있다면 전처리 시간도 n배수만큼 줄일 수 있을지 확인해보기로 했습니다. 만약 컴파일할 타깃 cpp 파일을 1개로 줄여서 산출물과 중복 모두 제거하면, 어느 정도 빌드 속도가 빨라질까요?

 

 

상황별 테스트

단일 cpp 파일 컴파일 테스트

위에서 세팅했던 테스트 소스를 cpp 파일 하나에 다 모아서, 전처리 결과를 살펴보겠습니다.

 

cpp 카피 소스
단순하게 모든 cpp 파일 내용을 하나로 카피한 소스

 

$ cl.exe /E merge.cpp > precompile_merge.txt

 

최적화 컴파일러
cl.exe /E 실행

 

전처리 파일 용량
전처리 후 파일 용량

 

전처리를 한 파일이 1개였으므로, 산출물도 1개만 나왔습니다. 파일 용량은 919,895바이트가 됐습니다. 약 0.9MB 정도입니다. 3개 파일이었을 때 약 3MB였던 용량에 비해 약 3분의 1 정도로 줄었습니다. 용량이 줄어든 만큼, 빌드 속도도 빨라졌지 않았을까요? 비주얼 스튜디오에서 비교 테스트를 해보겠습니다.

 

비주얼 스튜디오
비주얼 스튜디오에서 빌드 시간 비교 테스트

 

비주얼 스튜디오에서 확인해보니, 3개 파일을 1개 파일로 합친 것만으로 빌드 시간이 728ms에서 492ms로 줄어든 것을 볼 수 있었습니다. 링크 단계 시간을 제외하고 계산해보면 350ms에서 131ms로 줄어들었습니다. 빌드 시간도 약 3분의 1정도로 단축됐습니다.

 

파일 개수를 줄인 것만으로 전처리와 컴파일 속도는 3배 빨라졌고, 용량은 3분의 1로 줄었습니다. 분명 효과는 확실합니다.

 

이미 다들 예상하시겠지만, 이렇게 1개 파일만으로 작업한다면 소스 관리는 어떻게 해야 할지 아득합니다. 당연히 유지보수가 힘들 수밖에 없습니다. 또한, 파일 크기가 일정 크기를 넘어서면 컴파일러 메모리 사용 초과로 인해 컴파일 자체가 되지 않습니다. 파일 크기 제한은 비주얼 스튜디오 속성 페이지에서 ‘/bigobj’ 옵션을 설정해서 ‘.obj’ 파일 수용 범위를 늘려줘야 합니다. 자세한 내용은 공식 문서를 확인하시면 됩니다.

 

즉, 단순히 빌드 속도 개선을 위해 1개 파일로 모으는 방법은 현업 프로젝트에서는 실현 불가능하다고 봐야 합니다.

 

 

cpp 파일 개수를 유지하면서 단일 파일로 컴파일하는 방법

그렇다면, cpp 파일 개수는 유지하면서 단일 파일로 컴파일하는 방법은 없을까요? 우선, ‘#include’에 헤더 파일만 넣을 수 있다는 상식을 버려야 합니다. cpp 파일도 ‘#include’에 넣을 수 있으며, 실제로 cpp 파일을 병합(merge)한 것과 동일하게 동작합니다. 실제로는 어떠한지 확인해보겠습니다.

 

cpp 파일 추가
include에 cpp 파일을 추가

 

‘main.cpp’안에서 ‘#include “a.cpp”와 ‘#include “b.cpp”만 추가했습니다. cpp 파일은 헤더 파일보다 아래에 추가해야 하니, 꼭 주의하셔야 합니다. 또한, 비주얼 스튜디오에서 ‘a.cpp’와 ‘b.cpp’는 컴파일에서 제외하는 옵션을 설정해야, 중복 링크 에러가 발생하지 않습니다. 이제 전처리 단계를 실행해보겠습니다.

 

$ cl.exe /E main.cpp > precompile_main_2.txt

 

cl 실행
cl.exe /E 실행

 

파일 용량
전처리 후 파일 용량 비교

 

전처리 이후, 단일 cpp 파일로 테스트했던 결과와 비교해도 큰 차이가 없는 산출물이 나왔습니다. 빌드 속도도 빨라졌고 cpp 파일 개수도 유지했으므로, 소스관리와 유지보수에 대한 걱정을 덜 수 있게 됐습니다. 그래도 너무 많은 파일을 모으기보다는 적당히 분산해야 수용 용량 내에서 컴파일러가 원활히 동작하므로, 잘 분산해서 사용하셔야 합니다.

 

 

윈도우 프로젝트라면 초간단하게

윈도우 프로젝트라면 정말 간단하게 위 방법을 적용할 수 있습니다. 단, 비주얼 스튜디오 2017에서는 베타 기능으로 제공되고 있으므로, 비주얼 스튜디오 2019 이상에서 쓰시길 추천합니다.

 

유니티 빌드
비주얼 스튜디오 2019의 속성에 Unity 빌드 설정 가능

 

비주얼 스튜디오 2019 이상에서는 ‘프로젝트 → 속성 → 고급’에서 빌드 설정을 기본 기능으로 제공하고 있습니다.

 

유니티 빌드
비주얼 스튜디오 2019에서 유니티 빌드 소스 개수 조정 설정 화면

 

만약 파일의 최대 소스 개수를 변경해야 한다면, ‘프로젝트 → 속성 → C/C++ → Unity 빌드 옵션’에서 최소 소스 개수와 최대 소스 수로 포함할 파일 개수를 조절할 수 있습니다. 단, 이 옵션은 위에 있던 ‘Unity(JUMBO) 빌드 사용’을 활성화해야만 나타나므로, 보이지 않으시다면 유니티 빌드 사용 설정을 먼저 확인해 보셔야 합니다.

 

 

집에 일찍 가자

현업 프로젝트에서는 cpp 파일에 중복된 헤더가 많았던 만큼, 더 큰 효과가 나오기도 했습니다. 실제로 인크레디빌드를 쓰면서도 컴파일 시간이 20분 이상 걸렸던 프로젝트에서는 위 방법을 써서 2분 30초로 줄였습니다. 로컬 테스트에서 50분 이상 걸리던 빌드 시간을 10분 안쪽으로 당겼던 사례도 나왔습니다.

 

간혹, 헤더 정리나 소스 관리 전략을 이미 잘해둔 경우에는 큰 단축 효과를 못 보기도 했습니다. 그래도 30분 이상 걸리던 빌드를 10분 이내로 줄일 수 있다면, 우리는 새로 확보한 20분을 어디에 쓸지 고민해야 하는 행복회로를 돌릴 수 있지 않을까요?

 

단축한 시간에 무엇을 할지 고민하시기보다는, 우선은 집에 일찍 가는 것을 목표로 하시길 추천해 드립니다. 이상 워라밸 가디언으로 활동하는 넷마블 기술분석팀 김범진이었습니다.

 

<원문>

https://bit.ly/3IENXls

좋아요

댓글

공유

공유

댓글 0
작가
85
명 알림 받는 중

작가 홈

작가
85
명 알림 받는 중
넷마블 기술 블로그(https://netmarble.engineering)는 ‘넷마블’이라는 엔진을 기술로 다듬고 개선하는 과정과 그 과정을 이끌어 가는 엔지니어의 이야기를 전하는 넷마블 엔지니어의 플레이 그라운드입니다.

좋아요

댓글

스크랩

공유

공유

요즘IT가 PICK한 뉴스레터를 매주 목요일에 만나보세요

요즘IT가 PICK한 뉴스레터를
매주 목요일에 만나보세요

뉴스레터를 구독하려면 동의가 필요합니다.
https://auth.wishket.com/login