Featured image of post [Compiler 03] Introduction: Low-latency 컴파일러·빌드 최적화

[Compiler 03] Introduction: Low-latency 컴파일러·빌드 최적화

Low-latency 컴파일러·빌드 최적화 트랙의 도입 챕터입니다. 옵션 설계와 LTO/PGO, 인라이닝·코드 생성 분석의 책임 범위를 정리하고, 동일 벤치마크로 설정 변경을 검증하는 방법과 이 트랙을 마친 후 달성할 학습 목표를 안내합니다.

이 트랙은 “코드를 바꾸지 않고도 성능을 바꾸는 영역”을 책임집니다. µs 단위 최적화에서는 인라이닝·벡터화·분기 형태 같은 코드 생성 결과가 수치에 직접 영향을 주기 때문에, 빌드와 컴파일러를 설계 대상으로 다룹니다. 이 챕터에서는 트랙의 책임 범위·경계·커리큘럼·측정 기준와 이 트랙을 마친 후 달성할 학습 목표를 정리합니다.

왜 컴파일러·빌드 최적화인가 (동기)

같은 C++ 소스라도 최적화 플래그(-O2 vs -O3), LTO(Link-Time Optimization) 유무, PGO(Profile-Guided Optimization) 적용 여부에 따라 생성되는 기계어와 실행 시간이 달라집니다. 그 폭은 워크로드·컴파일러 버전·타겟 아키텍처에 따라 크게 갈리므로 고정된 수치로 단정하기 어렵고, 이 트랙의 각 챕터는 “일반적으로 몇 %“보다 자신의 벤치마크로 직접 재보는 절차를 우선합니다. 인라이닝 실패나 코드 크기 증가로 오히려 느려지는 회귀도 발생할 수 있습니다. 이 트랙은 그 선택을 측정 가능하게 하고, 언제 무엇을 쓸지 판단할 수 있도록 구성되어 있습니다.

이 트랙이 책임지는 범위

소스 코드를 한 줄도 바꾸지 않고 성능을 바꿀 수 있는 네 가지 축(옵션·링크타임·프로파일·코드생성)이 이 트랙의 범위입니다.

  • 최적화 옵션 설계: 릴리즈/디버그/프로파일링 빌드 전략, -O0~-Ofast·/O1·/O2·/Ox의 의미와 trade-off
  • LTO/ThinLTO, PGO: 적용 방법, ThinLTO trade-off, PGO 전/후·LTO on/off 성능·크기 검증
  • 인라이닝 실패 원인 분석: 가시성, ODR/ABI, 코드 크기 제한; 인라이닝 리포트 확인 (Tr.02 인라이닝 유도와 연계)
  • 코드 생성 형태 이해: 어셈블리 레벨 확인, 함수 경계/호출 규약, hot 함수 형태 해석, 벡터화 여부 진단(자동 벡터화 성공·실패를 컴파일러 리포트로 확인, 심화 SIMD 코드 작성 자체는 Tr.08에서 다룸)

이 트랙이 다루지 않는 것 (경계)

빌드·컴파일러가 “이미 있는 코드"에서 짜낼 수 있는 성능을 다루는 트랙이므로, 코드 자체의 설계나 하드웨어 실행 방식의 근본 원인은 범위 밖입니다.

  • 알고리즘/데이터 구조 선택 자체 → 메모리/데이터 구조 트랙 또는 별도 설계
  • 락 경합/스레드 구조 같은 동시성 설계 → 동시성 트랙
  • CPU 마이크로아키텍처의 하드 원인 분석 → CPU 트랙
  • 루프 언롤링·벡터화 심화 최적화 자체 작성(SIMD 코드를 손으로 짜거나 intrinsics로 벡터화하는 구현 자체) → 극한 최적화 기법 트랙(Tr.08). 이 트랙은 그 결과를 컴파일러가 자동 벡터화했는지 진단하는 데까지만 책임집니다.
  • 빌드 시스템 자체 설계(CMake/Bazel 타겟 구조, 증분 빌드·원격 캐시 아키텍처) → 12장(빌드 병렬화)은 ccache/distcc/sccache로 빌드 시간을 줄이는 도구 적용만 다루며, 빌드 시스템 설계 자체는 이 트랙 밖입니다.

트랙 범위와 경계를 흐름으로 보면 다음과 같습니다.

flowchart LR
  subgraph inscope [이 트랙 범위]
    A["최적화 플래그"]
    B["LTO / PGO"]
    C["인라이닝 진단"]
    D["코드 생성 분석"]
    E["빌드·도구"]
  end
  subgraph outscope [경계 밖]
    F["알고리즘 설계"]
    G["동시성 설계"]
    H["CPU 마이크로아키텍처"]
  end
  inscope --> outscope

커리큘럼

난이도 범례: 기초(입문) · 중급(실무 핵심) · 심화(깊은 분석·전문 주제) · 전문(극한·니치). Tr.NNoptimization-NN-* 트랙을 가리킵니다.

처음 읽는다면 01 → 02 → 04 → 05 → 06으로 빌드와 코드 생성의 큰 흐름을 먼저 잡고, 이후 03(PGO) → 15(AutoFDO)로 넘어가는 것을 권장합니다. 특히 PGO·AutoFDO는 단순히 도구를 켜는 문제가 아니라 대표 workload를 어떻게 수집·검증하느냐가 핵심이므로, 앞 장의 측정 기준을 먼저 익혀 두는 편이 안전합니다.

챕터제목난이도핵심 내용
01최적화 플래그기초-O2/-O3/-Ofast 플래그별 동작과 trade-off
02LTO/ThinLTO중급Link-Time Optimization 실전 적용과 검증
03PGO 워크플로우심화Profile-Guided Optimization 실전 워크플로우와 프로파일 대표성 검증
04컴파일러 비교중급GCC vs Clang vs MSVC 최적화 차이점
05인라이닝 진단심화컴파일러 관점 인라이닝 실패 진단 (가시성, ODR, ABI, 코드 크기); Tr.02 인라이닝 유도와 연계
06코드 생성 분석심화어셈블리 레벨 코드 생성 분석
07함수 멀티버저닝전문CPU 기능별 함수 다중 버전 생성
08컴파일러 내장 함수심화컴파일러 intrinsics 카탈로그
09Sanitizer 오버헤드중급AddressSanitizer/UBSan 등의 성능 영향
10디버그 정보와 성능중급디버그 심볼과 성능, 릴리즈 빌드 전략
11C++20 Modules중급Modules 빌드 시간과 런타임 성능 영향
12빌드 병렬화 전략중급ccache, distcc, sccache 활용과 빌드 시간 최적화
13Static Analyzer중급성능 관련 정적 분석 경고와 활용
14BOLT·후링크 최적화전문Post-link layout 최적화 개념·적용 판단·Tr.03 빌드 파이프라인과의 연동
15AutoFDO 워크플로우심화AutoFDO 수집·변환·적용과 PGO(instrumented) 대비 운영 비용 비교; 대규모 서버 플릿에서의 지속 최적화(Denis Bakhvalov, Performance Analysis and Tuning on Modern CPUs Ch.12.7 PGO/BOLT/Propeller 참고)

루프 벡터화·SIMD 구현 자체와 빌드 시스템(CMake/Bazel) 설계는 위 15개 챕터 어디에도 포함되지 않습니다 — 각각 Tr.08과 이 트랙 밖의 별도 주제로 의도적으로 제외했습니다.

측정과 검증 (이 트랙 기준)

  • 컴파일 산출물 비교: 인라이닝 여부, 코드 크기, hot 함수 형태 (어셈블리·최적화 리포트)
  • 성능 비교: PGO 전/후, LTO on/off를 동일 벤치마크와 대표 workload로 측정; 평균·분포·회귀 여부 확인
  • 회귀 감지: 빌드 설정 변경이 성능에 미치는 영향을 CI 등으로 자동화해 주기적으로 검증

동일 소스·동일 플래그에서 컴파일러만 바꾼 경우(GCC vs Clang vs MSVC)도 같은 벤치마크로 비교하는 것을 권장합니다.

측정 시 유의사항

벤치마크는 핫패스를 잘 커버하는 입력으로 설계해야 합니다. 한두 번의 실행보다는 반복 실행 후 평균·표준편차(또는 백분위)를 보고, 가능하면 CPU 고정·배경 부하 최소화 등 환경을 맞춰 재현 가능하게 측정합니다. Sanitizer가 켜진 빌드로 성능을 측정하면 안 되며, 릴리즈 빌드(-O2 또는 -O3, LTO/PGO 적용 여부는 목적에 맞게)로 측정합니다.

주의할 점 (비판적 시각)

빌드·컴파일러 최적화는 만능이 아닙니다. -O3나 LTO를 켜면 일부 워크로드에서는 코드 크기 증가로 I-cache 압박이 생겨 오히려 느려질 수 있고, PGO는 프로파일이 실제 배포 환경을 대표하지 않으면 잘못된 분기 예측으로 성능이 나빠질 수 있습니다. 그래서 이 트랙의 모든 권장사항은 “무조건 켠다"가 아니라 자신의 프로젝트에서 동일 벤치마크로 이득과 회귀를 직접 확인한 뒤 도입하는 것을 전제로 합니다. CI에서는 릴리즈 빌드로 성능 회귀 테스트를 주기적으로 돌리고, 빌드 설정을 바꿀 때는 변경 전후 수치를 비교해 두는 습관이 중요합니다.

각 챕터 읽는 순서와 연계

01(최적화 플래그) → 02(LTO/ThinLTO) → 03(PGO) 순으로 읽으면 “빌드 설정 기초"를 먼저 다집니다. 04(컴파일러 비교)는 01–03과 독립적으로 참고할 수 있고, 05(인라이닝 진단)는 Tr.02(인라이닝 유도)과 연계됩니다. 06(코드 생성 분석)은 01·05와 함께 어셈블리·인라이닝 확인에 쓰이고, 07–14는 멀티버저닝·내장 함수·Sanitizer·디버그 정보·Modules·빌드 병렬화·정적 분석·BOLT(후링크)를 각각 다룹니다. 필요한 주제만 골라 읽어도 되지만, 00·01·02를 먼저 읽으면 트랙 전체 맥락을 잡기 쉽습니다.

추천 선행/병행 트랙

이 트랙은 “무엇을 측정할지"는 다루지 않으므로, 측정 도구를 먼저 갖추고 인접 코드 영역과 병행하는 편이 안전합니다.

  • 선행: Low-latency Profiling & Performance Analysis (Tr.01) — 프로파일링과 벤치마크 방법을 먼저 익히면 이 트랙의 “측정·검증"을 적용하기 쉽습니다.
  • 병행: Low-latency C++ Language Optimization (Tr.02), Memory & Data Layout (Tr.04) — 인라이닝 유도·메모리 레이아웃은 코드 변경 영역이지만, 컴파일러가 생성하는 코드 형태와 맞물려 있으므로 병행 학습을 권장합니다.

이 트랙을 마친 후 달성할 목표 (학습 성과)

이 트랙을 끝까지 읽고 실습한 후, 다음을 할 수 있어야 합니다.

  • 최적화 플래그(-O0~-Ofast, /O1·/O2·/Ox)의 의미와 trade-off를 설명하고, 릴리즈/디버그/프로파일 빌드 전략을 설계할 수 있다.
  • LTO·ThinLTO를 활성화하고, LTO on/off 성능·크기 차이를 동일 벤치마크로 검증할 수 있다.
  • PGO 3단계 워크플로우를 적용하고, 프로파일 대표성과 회귀 검증을 고려할 수 있다. AutoFDO(챕터 15)의 샘플링 기반 워크플로우와 instrumented PGO의 운영 비용·프로파일 품질 차이를 설명할 수 있다.
  • GCC·Clang·MSVC의 최적화 차이를 영역별(벡터화·인라이닝·루프)로 비교하고, 플랫폼별 선택 근거를 말할 수 있다.
  • 인라이닝 실패 원인(가시성, ODR/ABI, 코드 크기)을 진단하고, 인라이닝 리포트와 Tr.02(인라이닝 유도)을 연계할 수 있다.
  • 어셈블리 레벨에서 코드 생성 형태(함수 경계·호출 규약)를 확인하고, hot 함수 형태를 해석할 수 있다.
  • 함수 멀티버저닝·컴파일러 내장 함수를 상황에 맞게 선택하고, Sanitizer 오버헤드와 디버그 정보 전략을 설명할 수 있다.
  • C++20 Modules빌드 병렬화(ccache, distcc, sccache)로 빌드 시간을 다루고, 정적 분석 경고를 성능 회귀와 연계할 수 있다.

평가 기준과 이 장을 읽은 후 확인

  • 트랙의 책임 범위경계(다루지 않는 것)를 구분해서 설명할 수 있는가?
  • 측정과 검증이 “동일 벤치마크"를 전제로 함을 이해하고, 회귀 감지 자동화의 필요성을 말할 수 있는가?
  • 커리큘럼 01–15의 선후 관계와 각 챕터의 핵심 내용을 한눈에 말할 수 있는가?
  • 커리큘럼 표와 “다음 장에서는” 링크를 바탕으로 지금 바로 읽을 챕터를 고를 수 있는가?

용어 정리 (이 챕터에서 쓰는 말)

용어설명
LTOLink-Time Optimization; 링크 시점에 여러 번역 단위를 합쳐 인라이닝·상수 전파 등을 적용하는 최적화
ThinLTO전체 프로그램을 한 덩어리로 하지 않고 모듈 단위로 나누어 병렬에 가깝게 처리하는 LTO 방식
PGOProfile-Guided Optimization; 실행 프로파일을 수집한 뒤 그 정보를 반영해 다시 컴파일하는 최적화
TUTranslation Unit; 전처리 후 하나의 컴파일 단위가 되는 소스
인라이닝함수 호출을 호출부에 코드를 삽입하는 방식으로 치환하는 최적화

핵심 요약

항목요약
트랙 범위코드 변경 없이 빌드·컴파일러 설정으로 성능을 다루는 영역
핵심 주제최적화 플래그, LTO/PGO, 인라이닝 진단, 코드 생성 분석, 빌드 도구
경계알고리즘·동시성 설계·CPU 마이크로아키텍처는 별도 트랙
검증동일 벤치마크로 설정 변경 전후 성능·크기 비교, 회귀 자동화

다음 장에서는

최적화 플래그(-O2/-O3/-Ofast)의 의미와 trade-off, 릴리즈/디버그/프로파일 빌드 전략을 다룹니다.

최적화 플래그: -O2/-O3/-Ofast (챕터 01)

시리즈 전체 로드맵

12개 트랙의 권장 순서·심화 진입 조건은 Low-latency 최적화 시리즈 개요에서 정리합니다.