Home PGO (Profile Guided Optimization, 프로필 기반 최적화)
Post
Cancel

PGO (Profile Guided Optimization, 프로필 기반 최적화)

(2023/11/05 업데이트)

PGO (Profile Guided Optimization, 프로필 기반 최적화)

프로파일링 옵션을 추가한 프로그램을 실행하면 프로필이라는 일종의 사용 통계 데이터가 남는다. 이 프로필 파일을 통해 다음 컴파일 시에 최적화를 해주는 기능.

네이티브 코드(C or C++)에서만 가능하고, 관리코드(C# 등)와 네이티브-관리 혼합(C++/CLI)에서는 불가능하다. 하지만 .NET6 부터 동일한 기능을 사용할 수 있도록 Dynamic PGO 라는 기능이 추가되었고, 기존의 PGO는 Static PGO 라고 칭하게 되었다. (Dynamic PGO는 다음 포스팅에 이어서 설명할 예정)


PGO (=Static PGO) 프로세스

  1. /GL 옵션을 컴파일 옵션에 추가하면 런타임 동작을 캡처할 수 있는 obj 파일들이 나온다.

  2. GL옵션을 사용해서 뽑은 obj 파일들은 프로파일링을 옵션을 켜야만 링크가 가능하다. 링커 옵션에 /LTCG, /GENPROFILE와 같은 옵션을 추가하여 빌드 시 프로파일링을 위한 바이너리가 만들어진다.

  3. 이 바이너리를 실행하면 일종의 통계 파일인 .pgd 파일이 생성됨.

  4. 링커에 USEPROFILE 옵션과 함께 .pgd 파일을 설정하면 PGO가 적용된 최적화 빌드를 생성할 수 있다.

여기서 컴파일러와 링커를 둘다 사용하고 있는 것에 의문이 있을 수 있는데 후술하도록 하겠다.


PGO 최적화 요소

.pgd 파일에는 다음과 같은 정보가 기록된다.

  • 코드 블럭/함수 의 호출 횟수
  • 조건문에서 분기별로 접근할 확률(e.g. x <= 0 조건문으로 들어가 코드를 실행하는 경우가 85% )
  • 함수 호출 계층 그래프
  • 변수와 명령줄 매개변수, 프로그램과 컴파일러 아키텍처 버전 등의 정보

.pgd 파일을 통해 다음과 같은 것들이 최적화된다.

  • 인라인 처리: 자주 호출되는 함수가 있을경우 함수 콜을 하는 부분에 함수의 코드를 그대로 치환해준다.

  • 가상 호출 추론: 가상 함수 호출시에 특정 클래스의 함수를 직접 캐스팅해서 호출하도록 코드를 수정한다. 캐스팅에 실패하면 기존 가상함수 호출 로직으로 다시 돌아간다.

  • 레지스터 할당: 자주 사용되는 내용을 레지스터에 캐싱해둔다.

  • 조건부 분기 최적화: 분기에서 자주 호출되는 코드블럭을 앞으로 배치해준다.

  • 데드 코드 분리: 자주 사용되지 않는 코드는 다른 페이지에 모아둔다.

그 외 다른 최적화 기법들이 적용된다.

기타 자세한 내용은 링크에서 확인 가능하다.


PGO는 기존 최적화와 무엇이 다른가?

PGO가 없이도 최적화는 이미 하고있다.

PGO 이전에 컴파일러 최적화를 통해 한 소스 파일 내에서 개선할 수 있는 기계적인 최적화가 이루어진다. 예를 들어, 정적인 코드 최적화가 가능하다. 동일한 연산을 여러번하는 경우 묶거나. 변수의 값이 변하지 않을경우 상수로 치환하거나, 의미없는 대입 연산과 사용하지 않는 변수는 아예 코드에서 없애버린다. 또한 특정 아키텍쳐에 맞게 캐시, 부동 소수점 옵션 최적화를 진행하기도 한다.

PGO는 컴파일러 최적화 + 런타임에 측정한 프로필 정보를 통한 최적화까지 진행한다. 자세한 내용은 위에 정리한 내용대로.

PGO를 하기 위해서는 기존의 컴파일러 최적화로는 불가능한 작업들이 있다. 컴파일러는 한 소스 코드 내에서 가능한 수준의 최적화만 가능하고 다른 파일을 참조하거나 전역 변수에 대한 컨트롤이 불가능하다. 또한 프로필 정보는 이미 컴파일된 코드에 대한 내용이기 때문에 재컴파일 하는 순간 의미가 없어져버린다.

그렇다면, 컴파일 시간 이후에 최적화가 필요해지고 이로 인해 만들어진 것이 LTCG(링크 타임 코드 생성)이다. 컴파일 타임에 할 수 없는 코드 최적화를 수행할 수 있게 만들어주는 기능.


참고하면 좋은 사이트

  • https://learn.microsoft.com/ko-kr/cpp/build/reference/genprofile-fastgenprofile-generate-profiling-instrumented-build?view=msvc-170

  • https://learn.microsoft.com/en-us/archive/msdn-magazine/2002/may/under-the-hood-link-time-code-generation

  • https://learn.microsoft.com/ko-kr/cpp/build/reference/ltcg-link-time-code-generation?view=msvc-170

  • https://devblogs.microsoft.com/cppblog/tag/profile-guided-optimization/

This post is licensed under CC BY 4.0 by the author.

GC DATAS (Dynamic Adaptation To Application Sizes, 동적 힙 갯수 조절)

Dynamic PGO (Dynamic Profile Guided Optimization, 동적 프로필 기반 최적화)