빌드 시간에 헤더 파일이 미치는 영향 문제 해결
Build Insights의 포함된 파일 및 포함 트리 뷰를 사용하여 #include
파일이 C 및 C++ 빌드 시간에 미치는 영향 문제를 해결합니다.
필수 조건
- Visual Studio 2022 17.8 이상.
- Visual Studio 설치 관리자를 사용하여 C++를 사용한 데스크톱 개발 워크로드를 설치하는 경우 C++ Build Insights는 기본적으로 사용하도록 설정됩니다.
설치된 구성 요소 목록이 표시됩니다. C++ Build Insights가 강조 표시되고 선택되어 있으면 설치된 것입니다.
또는 C++ 워크로드를 사용한 게임 개발:
설치된 구성 요소 목록이 표시됩니다. C++ Build Insights가 강조 표시되고 선택되어 있으면 설치된 것입니다.
개요
이제 Visual Studio에 통합된 Build Insights는 특히 AAA 게임과 같은 대규모 프로젝트의 경우 빌드 시간을 최적화하는 데 도움이 됩니다. 대규모 헤더 파일을 구문 분석하는 경우, 특히 반복적으로 구문 분석하는 경우 빌드 시간에 영향을 미칩니다.
Build Insights는 포함된 파일 뷰에서 분석을 제공하며, 이는 프로젝트에서 #include
파일 구문 분석이 미치는 영향을 진단하는 데 도움이 됩니다. 각 헤더 파일을 구문 분석하는 데 걸리는 시간과 헤더 파일 간의 관계를 보여 줍니다.
이 문서에서는 Build Insights의 포함된 파일 및 포함 트리 뷰를 사용하여 구문 분석에 가장 노력이 많이 드는 헤더 파일을 식별하는 방법과 미리 컴파일된 헤더 파일을 만들어 빌드 시간을 최적화하는 방법을 알아봅니다.
빌드 옵션 설정
Build Insights 데이터를 수집하기 전에 측정하려는 빌드 형식에 대한 빌드 옵션을 설정합니다. 예를 들어, x64 디버그 빌드 시간이 걱정된다면 디버그 및 x64에 대한 빌드를 설정합니다.
솔루션 구성 드롭다운에서 디버그를 선택합니다.
솔루션 플랫폼 드롭다운에서 x64를 선택합니다.
솔루션 구성 드롭다운이 표시됩니다. 디버그, 릴리스 및 구성 관리자에 대한 옵션이 있습니다. 솔루션 플랫폼 드롭다운이 x64로 설정되어 있습니다.
Build Insights 실행
선택한 프로젝트에서 이전 섹션에 설정된 디버그 빌드 옵션을 사용하여 프로젝트 이름>> 다시 빌드의 빌드 실행 인사이트 기본 메뉴에서 선택하여 Build>Insights를 실행합니다.< 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 Build Insights 실행>다시 빌드를 선택할 수도 있습니다. 빌드 대신 다시 빌드를 선택하여 현재 더러워진 소수의 파일뿐만 아니라 전체 프로젝트의 빌드 시간을 측정합니다.
빌드가 완료되면 ETL(이벤트 추적 로그) 파일이 열립니다. Windows TEMP
환경 변수가 가리키는 폴더에 저장됩니다. 생성된 이름은 컬렉션 시간을 기준으로 합니다.
포함된 파일 뷰
추적 파일은 빌드 시간을 보여 줍니다. 이 예에서는 16.404초였습니다. 진단 세션은 Build Insights 세션을 실행하는 데 소요되는 전체 시간입니다. 포함된 파일 탭을 선택합니다.
이 뷰에는 #include
파일을 처리하는 데 소요된 시간이 표시됩니다.
파일 경로 열에서 불 아이콘이 있는 여러 파일은 구문 분석하는 데 빌드 시간의 10% 이상을 차지하므로 강조 표시됩니다. winrtHeaders.h는 8.581초로 가장 크며, 빌드 시간 16.404초의 52.3%입니다.
파일 경로 열에서 일부 파일 옆에 불 아이콘이 표시되어 빌드 시간의 10% 이상을 차지함을 나타냅니다.
시간 [초, %] 열은 WCTR(벽시계 책임 시간)에서 각 함수를 컴파일하는 데 걸린 시간을 보여 줍니다. 이 메트릭은 병렬 스레드 사용을 기반으로 파일을 구문 분석하는 데 걸리는 벽시계 시간을 배포합니다. 예를 들어, 두 개의 서로 다른 스레드가 1초 내에 두 개의 서로 다른 파일을 동시에 구문 분석하는 경우 각 파일의 WCTR은 0.5초로 기록됩니다. 이는 병렬 실행 중에 각 파일이 소비하는 리소스를 고려하여 총 컴파일 시간에 대한 각 파일의 비례적 점유율을 반영합니다. 따라서 WCTR은 여러 컴파일 작업이 동시에 발생하는 환경에서 각 파일이 전체 빌드 시간에 미치는 영향을 더 잘 측정할 수 있습니다.
구문 분석 횟수 열에는 헤더 파일이 구문 분석된 횟수가 표시됩니다.
이 목록에서 강조 표시된 첫 번째 헤더 파일은 winrtHeaders.h
입니다. 전체 빌드 시간 16.404초 중 8.581초(즉 빌드 시간의 52.3%)가 걸립니다. 그다음으로 가장 비싼 것은 Windows.UI.Xaml.Interop.h
이고 그다음은 Windows.Xaml.h
입니다.
winrtHeaders.h
가 포함된 파일을 보려면 옆에 있는 펼침 단추를 클릭합니다. 구문 분석 횟수 열은 헤더 파일이 다른 파일에 포함된 횟수를 알려줌으로써 도움이 될 수 있습니다. 헤더 파일이 여러 번 포함될 수 있는데, 이는 미리 컴파일된 헤더 파일이나 리팩터링에 적합한 응시자라는 신호일 수 있습니다.
변환 단위 열에는 포함된 파일이 처리될 때 처리되고 있던 파일이 표시됩니다. 이 예에서는 Grapher.cpp
가 컴파일되는 동안 winrtHeaders.h
가 포함되었습니다.
샘플 프로젝트에 대한 포함 파일을 보여 주는 ETL 파일 예입니다. 파일 경로 열에서 winrtHeaders.h가 선택되고 확장됩니다. 빌드하는 데는 8.219초가 소요되며 이는 빌드 시간의 50.1%에 해당합니다. 해당 자식 노드는 Grapher.cpp이며 변환 단위로도 나열됩니다."
변환 단위 열은 헤더 파일이 여러 번 포함되고 가장 많이 발생하는 위치를 찾으려는 경우 어떤 파일이 컴파일되었는지 명확하게 하는 데 도움이 될 수 있습니다.
winrtHeaders.h
는 구문 분석하는 데 노력이 많이 든다는 것을 알고 있지만 더 자세히 알아볼 수 있습니다.
트리 뷰 포함
이 뷰에서 자식 노드는 부모 노드에 포함된 파일입니다. 이를 통해 헤더 파일 간의 관계를 이해하고 헤더 파일의 구문 분석 횟수를 줄일 수 있는 기회를 식별할 수 있습니다.
포함 트리 뷰를 보려면 ETL 파일에서 포함 트리 탭을 선택합니다.
프로젝트의 포함 트리를 표시합니다. 파일 경로 열에는 다른 파일을 포함하는 각 파일이 포함된 파일 수 및 구문 분석 시간과 함께 나열됩니다.
이 뷰에서 파일 경로 열에는 다른 파일을 포함하는 각 파일이 표시됩니다. 포함 개수는 이 헤더 파일에 포함된 파일 수를 나열합니다. 이 파일을 구문 분석하는 시간이 나열되며 확장되면 이 헤더 파일에 포함된 각 개별 헤더 파일을 구문 분석하는 시간이 나열됩니다.
앞서 winrtHeaders.h
구문 분석에 시간이 많이 걸리는 것을 확인했습니다. 파일 필터링 텍스트 상자에 winrtHeaders.h
를 입력하면 이름에 winrtHeaders.h
가 포함된 항목으로만 뷰를 필터링할 수 있습니다. winrtHeaders.h
옆에 있는 펼침 단추를 클릭하면 여기에 포함된 파일이 표시됩니다.
파일 경로 열에는 다른 파일을 포함하는 각 파일과 포함된 파일 수, 구문 분석하는 데 걸린 시간이 나열됩니다. winrtHeaders.h가 선택되고 확장되어 여기에 포함된 파일이 표시됩니다. Windows.UI.Xaml.Interop.h는 이러한 파일 중 하나이며 포함된 헤더 파일을 표시하도록 확장된 Windows.UI.Xaml.Interop.h를 표시하도록 확장됩니다.
winrtHeaders.h
에 Windows.UI.Xaml.Interop.h
가 포함되어 있음을 알 수 있습니다. 포함된 파일 뷰에서 이 작업도 구문 분석하는 데 시간이 많이 걸렸다는 점에 유념해야 합니다. Windows.UI.Xaml.Interop.h
옆에 있는 펼침 단추를 클릭하면 여기에 21개의 다른 헤더 파일이 포함된 Windows.UI.Xaml.h
가 포함되어 있는지 확인할 수 있으며 그중 2개도 핫 목록에 있습니다.
구문 분석에 가장 노력이 많이 드는 헤더 파일 중 일부를 식별하고 winrtHeaders.h
가 해당 파일을 가져오는 역할을 한다는 점을 확인하면 미리 컴파일된 헤더를 사용하여 winrtHeaders.h
를 더 빠르게 포함할 수 있음을 알 수 있습니다.
미리 컴파일된 헤더로 빌드 시간 개선
포함된 파일 뷰를 통해 winrtHeaders.h
이 구문 분석하는 데 시간이 많이 걸린다는 것을 알고 있고 포함 트리 뷰를 통해 구문 분석하는 데 시간이 많이 걸리는 다른 여러 헤더 파일이 winrtHeaders.h
에 포함되어 있다는 것을 알고 있으므로 PCH(미리 컴파일된 헤더 파일)을 빌드하여 PCH로 한 번만 구문 분석하여 속도를 높였습니다.
winrtHeaders.h
를 포함하기 위해 pch.h
를 추가합니다. 이는 다음과 같습니다.
#ifndef CALC_PCH
#define CALC_PCH
#include <winrtHeaders.h>
#endif // CALC_PCH
PCH 파일은 사용하기 전에 컴파일해야 하므로 pch.h
를 포함하는 임의로 이름이 pch.cpp
인 파일을 프로젝트에 추가합니다. 여기에는 한 줄이 포함됩니다.
#include "pch.h"
그런 다음 PCH를 사용하도록 프로젝트를 설정했습니다. 이는 프로젝트 속성에서 미리 컴파일된 헤더를 사용(/Yu)로 설정하고 미리 컴파일된 헤더 파일을 pch.h로 설정한 C/C++>미리 컴파일된 헤더를 통해 수행됩니다.
미리 컴파일된 헤더는 사용(/Yu)으로 설정됩니다. 미리 컴파일된 헤더 파일은 pch.h로 설정됩니다.
PCH를 사용하기 위해 winrtHeaders.h
를 사용하는 원본 파일의 첫 번째 줄에 포함합니다. 다른 포함 파일 앞에 와야 합니다. 또는 단순화를 위해 프로젝트 속성을 설정하여 솔루션의 모든 파일 시작 부분에 pch.h
을 포함하도록 프로젝트 속성 C/C++>고급>강제 포함 파일을 pch.h
으로 수정할 수 있습니다.
강제 포함 파일은 pch.h로 설정됩니다.
PCH에는 winrtHeaders.h
가 포함되어 있으므로 현재 포함된 모든 파일에서 winrtHeaders.h
를 제거할 수 있습니다. 컴파일러는 winrtHeaders.h
가 이미 포함되어 있음을 인식하고 이를 다시 구문 분석하지 않기 때문에 꼭 필요한 것은 아닙니다. 일부 개발자는 명확성을 위해 또는 PCH가 리팩터링되어 해당 헤더 파일을 더 이상 포함하지 않을 수 있는 경우 원본 파일에 #include
를 유지하는 것을 선호합니다.
변경 사항 테스트
먼저 프로젝트를 정리하여 이전과 동일한 파일 빌드를 비교하는지 확인합니다. 프로젝트 하나만 정리하려면 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 프로젝트만><프로젝트 이름>만 정리를 선택합니다.
이 프로젝트는 이제 PCH(미리 컴파일된 헤더)를 사용하기 때문에 PCH를 빌드하는 데 소요된 시간은 한 번만 발생하므로 측정할 필요가 없습니다. pch.cpp
파일을 로드하고 Ctrl+F7을 선택하여 해당 파일만 빌드하면 됩니다. 솔루션 탐색기에서 pch.cpp
를 마우스 오른쪽 단추로 클릭하고 Compile
을 선택하여 이 파일을 컴파일할 수도 있습니다.
이제 프로젝트를 마우스 오른쪽 단추로 클릭하고 프로젝트 전용>빌드 시 Build Insights 실행을 선택하여 솔루션 탐색기에서 Build Insights을 다시 실행합니다. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 Build Insights 실행>빌드를 선택할 수도 있습니다. 이번에는 다시 빌드하지 않는 것이 좋습니다. 측정하려고 하지 않은 PCH가 다시 빌드되기 때문입니다. 앞서 프로젝트를 정리했는데, 이는 일반 빌드가 측정하려는 모든 프로젝트 파일을 컴파일한다는 것을 의미합니다.
ETL 파일이 나타나면 빌드 시간이 16.404초에서 6.615초로 단축된 것을 확인할 수 있습니다. winrtHeaders.h
를 필터 상자에 넣으면 아무 것도 나타나지 않습니다. 이는 미리 컴파일된 헤더에 의해 끌어오기 때문에 구문 분석에 소요되는 시간이 이제 무시할 수 있기 때문입니다.
이 예에서는 미리 컴파일된 헤더가 C++20 이전의 일반적인 솔루션이기 때문에 사용됩니다. 그러나 C++20부터는 헤더 단위 및 모듈과 같이 헤더 파일을 포함하는 더 빠르고 덜 불안정한 다른 방법이 있습니다. 자세한 내용은 헤더 단위, 모듈 및 미리 컴파일된 헤더 비교를 참조하세요.
뷰 간 이동
포함된 파일 및 포함 트리 뷰에는 몇 가지 탐색 기능이 있습니다.
- 포함된 파일 또는 포함 트리에서 파일을 두 번 클릭하거나 Enter 키를 눌러 해당 파일의 소스 코드를 엽니다.
- 다른 뷰에서 해당 파일을 찾으려면 헤더 파일을 마우스 오른쪽 단추로 클릭합니다. 예를 들어, 포함된 파일 뷰에서
winrtHeaders.h
를 마우스 오른쪽 단추로 클릭하고 포함 트리에서 찾기를 선택하면 포함 트리 뷰에서 볼 수 있습니다.
또는 포함 트리 뷰에서 파일을 마우스 오른쪽 단추로 클릭하여 포함된 파일 뷰로 이동할 수 있습니다.
팁
- ETL 파일을 보다 영구적인 위치에 파일>다른 이름으로 저장하여 빌드 시간을 기록할 수 있습니다. 그런 다음 이를 향후 빌드와 비교하여 변경 내용으로 인해 빌드 시간이 개선되는지 확인할 수 있습니다.
- 실수로 Build Insights 창을 닫은 경우 임시 폴더에서
<dateandtime>.etl
파일을 찾아서 다시 엽니다.TEMP
Windows 환경 변수는 임시 파일 폴더의 경로를 제공합니다. - WPA(Windows Performance Analyzer)를 사용하여 Build Insights 데이터를 자세히 살펴보려면 ETL 창 오른쪽 하단에 있는 WPA에서 열기 단추를 클릭합니다.
- 열 순서를 변경하려면 열을 끕니다. 예를 들어, 시간 열을 첫 번째 열로 이동하는 것이 좋습니다. 열 머리글을 마우스 오른쪽 단추로 클릭하고 표시하지 않으려는 열을 선택 취소하여 열을 숨길 수 있습니다.
- 포함된 파일 및 포함 트리 뷰는 관심 있는 헤더 파일을 찾을 수 있는 필터 상자를 제공합니다. 제공한 이름과 부분적으로 일치합니다.
- 헤더 파일에 대해 보고된 구문 분석 시간이 해당 파일을 포함하는 파일에 따라 다른 경우가 있습니다. 이는 확장되는 헤더 부분, 파일 캐싱 및 기타 시스템 요인에 영향을 미치는 다양한
#define
의 상호 작용으로 인해 발생할 수 있습니다. - 포함된 파일 또는 포함 트리 뷰에서 표시하려는 내용을 잊어버린 경우 탭을 마우스로 가리키면 뷰를 설명하는 도구 설명을 볼 수 있습니다. 예를 들어, 포함 트리 탭를 마우스로 가리키면 도구 설명에 "자식 노드가 부모 노드에 포함된 파일인 모든 파일에 대한 포함 통계를 표시하는 뷰"라고 표시됩니다.
- 헤더 파일의 모든 시간을 집계한 기간이 전체 빌드 기간보다 긴 경우(예:
Windows.h
)를 볼 수 있습니다. 무슨 일이 일어나고 있는지 헤더가 동시에 여러 스레드에서 구문 분석되고 있다는 것입니다. 두 스레드가 동시에 헤더 파일을 구문 분석하는 데 1초를 소비한다면 벽시계 시간이 1초만 지나도 빌드 시간은 2초입니다. 자세한 내용은 WCTR(벽시계 책임 시간)을 참조하세요.
문제 해결
- Build Insights 창이 표시되지 않으면 빌드 대신 다시 빌드를 수행합니다. 실제로 아무것도 빌드되지 않으면 Build Insights 창이 나타나지 않습니다. 마지막 빌드 이후 파일이 변경되지 않은 경우일 수 있습니다.
- 관심 있는 헤더 파일이 포함된 파일 또는 포함 트리 뷰에 표시되지 않는 경우 빌드되지 않았거나 빌드 시간이 나열될 만큼 중요하지 않습니다.
참고 항목
Insights 팁 및 요령 빌드
헤더 단위, 모듈 및 미리 컴파일된 헤더 비교
Visual Studio의 Build Insights 동영상 - Pure Virtual C++ 2023
더 빨라진 C++ 빌드, 간소화된 새로운 시간 메트릭
빌드 시간에 함수 인라인 처리 문제 해결
vcperf 및 Windows 성능 분석기