C ++ 컴파일 프로세스 프로파일 링


80

나는 다소 큰 템플릿 헤더 전용 C ++ 라이브러리를 작성하는 경향이 있으며 사용자는 일반적으로 컴파일 시간에 대해 불평합니다. 그 문제에 대해 생각 해보니 시간이 어디로 가는지 전혀 모른다는 생각이 들었 습니다 . g ++, icc 및 xlC와 같은 일반적인 컴파일러로 C ++ 컴파일 프로세스를 프로파일 링하는 간단한 방법이 있습니까? 예를 들어 C ++ 컴파일의 각 단계 에서 얼마나 많은 시간이 소요되는지 알 수 있습니까?


2
stackoverflow.com/questions/82128/... 비주얼 스튜디오를위한
KARTHIK T에게

2
@KarthikT 제안에 감사하지만 그보다 훨씬 더 세밀한 정보에 관심이 있습니다 (더 많은 컴파일러에 대해). 예를 들어 헤더 전용 라이브러리에서 하나의 개체 파일을 빌드 하는 경우 시간이 어디로 갔는지 어떻게 알 수 있습니까?
Jack Poulson 2012

나는 그것보다 더 미세한 것을 찾을 수 없습니다. 죄송합니다.
Karthik T

답변:


66

들어 GCC디버깅 옵션을 찾을how much time is spent within each of the phases of C++ compilation?

-큐 컴파일러가 컴파일 될 때 각 함수 이름을 인쇄하고 완료되면 각 패스에 대한 통계를 인쇄합니다.

-ftime-report 컴파일러가 각 패스가 완료 될 때 소비 된 시간에 대한 통계를 인쇄하도록합니다.

패스는 GCCINT 9 : 컴파일러의 패스 및 파일에 설명되어 있습니다.

-v -ftime-report여기에서 단일 소스 파일의 g ++ 컴파일 출력을 게시 하여 논의 할 수 있습니다. GCC 메일 링리스트 에 도움이 될 수 있습니다 .


컴파일러를 들어 GCC 이외의 (또는 GCC 개 고대의 이상 3.3.6 )이 글의 다른 옵션을 참조하십시오.


2
추신 : -Q출력은 awk 또는 perl 스크립트에 의해 파악, 구문 분석 및 분석 될 수 있습니다. 또는 콘솔에서 함수 이름 인쇄를 볼 수 있습니다. 긴 일시 중지 후에 인쇄 된 것은 컴파일하기가 어려웠습니다.
osgx

함수 이름에 타이밍을 붙이는 방법 (해킹 g ++의 부족)이 있습니까? 스파게티 기능이 엉망인 200MB 파일이 있는데 어떤 함수를 컴파일하는 데 오래 걸리는지 모릅니다. 대부분은 빠르게 컴파일되며, 그 중 많은 수가 있습니다 (템플릿 무거운 코드이기도합니다). 나는 파이프와 스크립트를 생각하고 있었지만 파이프에는 약간의 버퍼가 있고 짧은 이름을 가진 함수는 더 많은 것이 인쇄 될 때까지 거기에 도착하지 못할 수 있습니다.
돼지

1
돼지, gcc / cgraphunit.c에서 grep 'quiet_flag'를 시도하고 gcc/toplev.c( announce_function - "함수 정의의 시작 부분이 구문 분석되면이 함수는 stderr에 함수 이름을 인쇄합니다"). 이것은 announce_function타임 스탬프 (gettimeofday) 인쇄를 추가하거나 버퍼링되지 않은 방식으로 출력을 다시 쓰는 지점 이 될 수 있습니다. 또는 다른 가능한 방법은 디버그 덤프 ( -fdump-rtl-all-all -fdump-tree-all-all -fdump-ipa-all-all) 를 활성화하는 것이지만 패스 당 1 개의 파일을 출력합니다. 패스 및 함수 당 1 개의 파일을 출력하도록 변환해야합니다 (생성 시간과 함께 많은 파일 가져 오기).
osgx 2015 년

14

거기에 있는 도구 거의 모든 컴파일러와 빌드 시스템에 유용 할 수있는 부스트 프로젝트에서이.

이 도구에는 및 매크로 호출을 사용하는 소스 코드 계측 이 필요 합니다. 그런 다음 이러한 매크로는 컴파일 타임에 특정 진단 (경고)을 생성하며, 인스턴스화 콜 스택과 함께 시간이 지정되고 수집됩니다 (결과적으로 빌드 및 시각화가 가능합니다.TEMPLATE_PROFILE_ENTER()TEMPLATE_PROFILE_EXIT() 하며, 스크립트에 의해 콜 그래프를 작성 됩니다. 나쁘지 않습니다, IMO.

그래도 아직 사용하지 않았습니다.


설명서 페이지에서 소스 코드 계측의 필요성을 보지 못했습니다. 어디서 읽었습니까?
lrineau

@Irineau, 출처. 이 도구는 또한 자동으로 계측을 수행하는 것처럼 보이는 몇 가지 스크립트를 제공합니다 (알 수없는 수준의 세분성).
ulidtko 2014

1
링크가 끊어졌습니다.
rustyx 2010 년

@rustyx는 당연 합니다. URL에서 svn .boost.org를 보고 21 세기 시계에서 ... 누군가 포크 / 미러 / 재 작성을 업로드 했습니까? 그래도 도움이 될 것입니다.
ulidtko 20.05.05

9

Clang 9 (이상)에는 -ftime-trace 플래그가있어 프로파일 링 보고서를 JSON (객체 파일 외에)으로 출력합니다.

이 파일을 Chrome ( chrome://tracing) 과 함께 제공되는 프로파일 러로 가져와 멋진 시각화를 얻을 수 있습니다.

그림

막대는 구문 분석해야하는 헤더와 각 헤더에 대해 구문 분석해야하는 특정 클래스 (및 아마도 다른 구성)에 해당합니다. 또한 특정 템플릿을 인스턴스화하는 데 소요 된 시간을보고합니다.



5

당신은 그것들을 어느 정도 분리 할 수 ​​있습니다 (나는 가정하고 있습니다 make)

  • 파일을 전처리하는 빌드 규칙 ( -E스위치 사용)과 .PHONY일반 바이너리 대상이 .o파일에 의존하는 것처럼 전 처리기 출력 파일에 의존하는 대상을 추가 합니다. 이 타겟을 구축하는 데 걸리는 시간 측정
  • 'PHONY모든 .o파일 에 종속 되지만 링크하지 않는 대상을 추가하십시오 . 이 타겟을 구축하는 데 걸리는 시간 측정 (깨끗한 상태에서)
  • 일반적인 바이너리의 클린 빌드를 수행하는 데 걸리는 시간 측정

이제 사전 처리, 컴파일 및 링크하는 데 걸리는 시간을 알 수 있습니다. 또한 -O0두 번째 및 세 번째 대상의 최적화 된 버전과 최적화되지 않은 버전 ( )을 비교 하여 최적화 프로그램에서 소요 된 시간을 확인할 수 있습니다.


응답 해 주셔서 감사합니다. 나는 이것이 C 프로그램에 충분하다고 생각하지만 하나 이상의 .o 파일을 빌드하지 않는 헤더 전용 C ++의 경우 거의 모든 시간이 단일 .o를 빌드하는 데 소비됩니다. 나는 찬성하고 있지만 누군가가 더 세밀한 접근 방식을 제안 할 것이라고 내 손가락을 건드릴 것입니다.
Jack Poulson

아, 그럼 어떤 코드가 가장 시간이 많이 걸리는 번역 단계에 관심이 없나요?
쓸모 없음

2
clang / llvm을 사용하는 경우 유사한 기술을 사용하여 백엔드 (llvm-opt)에서 프런트 엔드 (clang)를 분리 할 수 ​​있습니다. 백엔드에서는 최적화 그래프를 덤프하고 별도로 실행할 수도 있습니다. gcc에서 -O0과 -O3 사이의 빌드 시간을 비교하고 최적화에 소요 된 시간과 다른 곳에서 소요 된 시간의 차이를 확인할 수 있습니다. 그런 다음 옵티 마이저를 선택적으로 활성화하여 최악의 공격자 (있는 경우)를 확인할 수 있습니다.
Ze Blob

2

strace -e trace=process -f -r -ttt -T적어도 많은 프로세스로 나뉘어 진 g ++와 같은 컴파일러의 경우에서 일부 변형으로 약간의 견인력을 얻을 수 있습니다 .


0

다른 사람들은 -ftime-reportGCC에 대한 명령 줄 플래그를 이미 제안했습니다.이 플래그는 컴파일러가 각 컴파일 단계에서 소비 된 시간에 대한 통계를 인쇄하게합니다. 단점은 한 단위에 대한 요약 만 표시한다는 것입니다.

프로젝트 빌드 로그 파일이 주어지면 각 컴파일 단계에서 모든 단위에 대한 전체 요약을 인쇄 할 수 있는 Python 스크립트를 작성했습니다 . 또한 다른 단계로 정렬 할 수도 있습니다. 또한 두 개의 로그 파일을 비교할 수도 있습니다 (예 : 변경 사항의 영향을 이해하려는 경우).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.