[Rust] 프로필 기반 최적화 (profile-guided optimization: PGO)

프로필 기반 최적화(profile-guided optimization: PGO)는 극한의 최적화 기법 중 하나다.

이건 컴파일러가 컴파일을 한 다음에 그 프로그램을 돌려보고, 그 결과를 분석해서 다시 최적화를 하는 것이다.

최적화를 위해 프로파일러를 참조하기 때문에 프로필 기반 최적화라고 부른다.

당연히 컴파일타임은 저세상으로 간다.

pgo의 원리에 대한 것은 별도 포스트를 참조한다.
https://m.blog.naver.com/sssang97/223937776756




세팅하기

우선 필요한 모듈을 rustup으로 설치한다.
저거 하나만 있으면 된다.

rustup component add llvm-tools-preview

그리고 LLVM 도구 모음이 필요하다.
여기 들어가서 본인 OS에 맞는 installer를 받으면 된다.
https://releases.llvm.org/download.html
clang까지는 필요없고 llvm 도구만 있으면 된다.

깔아서 llvm-profdata라는 도구만 잘 실행되면 된다.




프로파일 데이터 모으기

최적화를 하려면 실제로 실행을 해서 데이터를 모아봐야 한다.

그러려면 컴파일할때 프로파일 데이터를 저장시키도록 지정을 해줘야 한다.
아래처럼 말이다.

일단 내 경우에는 상대경로로 .gitignore에 포함되는 target으로 지정했는데, 취향껏 지정해도 된다.

windows라면 아래 두 명령을 주면 될 것이고

$Env:RUSTFLAGS="-Cprofile-generate=./target/pgo-data" 
cargo build --release

linux-like라면 하나의 명령줄로도 가능하다.

RUSTFLAGS="-Cprofile-generate=./target/pgo-data" 
cargo build --release

그리고 빌드가 다 되면, 실행시켜서 이런저런 동작들을 다 돌려본다.

그럼 지정했던 경로로 프로파일 데이터들이 계속 쌓일 것이다.






프로파일 데이터 적용하기

그럼 이제 저걸로 최적화를 먹여보자.

우선 llvm-profdata로 로그들을 하나로 뭉쳐줘야 한다.

llvm-profdata merge -o ./target/pgo-data/merged.profdata ./target/pgo-data

그럼 이렇게 생성될 것이다.

이제 저걸 옵션에 주기만 하면 된다.

여기서는 조금 주의해야 하는게, 경로 설정을 절대경로로만 줘야 잘 찾는다.
상대경로는 안되더라.

윈도우즈에서

$Env:RUSTFLAGS="-Cprofile-use=경로"
cargo build --release

리눅스 계열에서

RUSTFLAGS="-Cprofile-use=경로"
cargo build --release

성능은 벤치마크를 해보진 않았지만
확실한건, 바이너리 사이즈 최적화는 끝내주게 먹힌다는 것이다.



참조
https://doc.rust-lang.org/rustc/profile-guided-optimization.html