Linux

clang toolchain의 위력 (빌드 최적화, build time profiling)

chbae 2024. 6. 6. 03:15
728x90

인포테인먼트 제품을 개발하고 있고 Yocto 프로젝트 기반의 임베디드 리눅스를 기반으로 하고 있다. Yocto 버전은 dunfell을 사용하다가 작년에 kirkstone으로 고생해서 마이그레이션을 해서 사용중이다.

 

컴포넌트 하나가 이전에 4시간 걸렸던 것이 LTO (Link Time Optimization) 옵션을 적용해서 2시간으로 줄었다. 이 컴포넌트는 ARXML 기반으로 프로토콜이 작성되어 있고 이것이 code generator을 통해 헤더와 코드가 생성되고 라이브러리가 생성되는 구조이다. 그렇기에 엄청나게 많은 파일이 linking 단계에서 사용되어 오래걸렸던 것이다. LTO는 빌드 시간이 더 걸릴 수 있다고 봤지만 이 경우에는 엄청나게 단축되었다.

 

3가지 variant가 있는데 최근 업그레이드 한 것중 하나가 5시간 빌드시간이 걸리는 것을 발견해서 다시 디버깅을 하였고 이 과정중에 clang에서 -ftime-trace옵션을 주면 빌드 타임 프로파일링이 가능하다는 것을 찾아서 clang을 우선 이 컴포넌트에 대해서 적용을 했다.

https://www.snsystems.com/technology/tech-blog/clang-time-trace-feature

 

위의 그림은 clang에서 -ftime-trace 옵션 [1]을 적용해서 나온 json파일을 chrome의 tracing 을 통해 visualization한 것이다. 이 외에도 Clang Build Analyzer [2] 으로도 분석할 수 있으니 아래 -ftime-trace 옵션과 분석에 대해서 자세히 알고 싶으면 아래 레퍼런스 링크를 참고하면 된다.

 

다시 clang으로 돌아와서, 기존에 gcc를 사용했을 때 어떤 variant에서는 5시간, 다른데서는 2시간, 또 다른데서는 1시간이 걸렸는데 단지 clang으로만 바꿨는데 10분내로 빌드 시간이 줄어들었다. 실로 엄청난 개선이다. 물론 아직 테스트 단계가 남아있지만 잘 될 것으로 기대한다.

 

좀 더 자세히 원인을 분석하기 위해 보니 위에서 이야기한 것처럼 linking에서 gcc는 단일 스레드를 사용했고 시리얼라이즈로 빌드가 되었던 것이고 clang은 linking 시간에 병렬로 하기 때문에 엄청나게 시간이 줄어든 것이였다.

출처: https://ost.51cto.com/posts/17919

 

위의 그림에서 LLVM LTO를 보면 지속적으로 메모리를 사용함을 알 수 있다. 이 이야기는 계속 병렬로 linking을 한다고 생각해도 무방하다. 실제로 htop으로 빌드할 때 비교해보면 gcc는 linking과정에 1-2개의 thread만 90~100%를 사용하지만 clang은 대부분의 thread가 사용되는 것을 볼 수 있었다.

 

정말 놀랄만한 결과이다. 5시간에서 10분이라니.. 추가적으로 python binding을 테스트를 위해 사용했는데 이것도 C기반의 테스트로 대체할 예정이여서 이를 disable하고 사용해보니 3-4분 정도 추가적으로 줄었다. 이제 clang으로 대체해야하나 .... 고민중이다.

레퍼런스