Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Gebruik de Opgenomen bestanden- en Include Tree-weergaven in Build Insights om de impact van #include-bestanden op de C- en C++-buildtijden te onderzoeken.
Vereiste voorwaarden
- Visual Studio 2022 17.8 of hoger.
- C++ Build Insights is standaard ingeschakeld als u de desktopontwikkeling met C++ workload installeert met behulp van het Visual Studio-installatieprogramma:
De lijst met geïnstalleerde onderdelen wordt weergegeven. C++ Build Insights is gemarkeerd en is geselecteerd, wat betekent dat deze is geïnstalleerd.
Of de gameontwikkeling met C++-workload:
De lijst met geïnstalleerde onderdelen wordt weergegeven. C++ Build Insights is gemarkeerd en is geselecteerd, wat betekent dat deze is geïnstalleerd.
Overzicht
Build Insights, nu geïntegreerd in Visual Studio, helpt u bij het optimaliseren van uw buildtijden, met name voor grote projecten zoals triple-A-games. Wanneer een groot headerbestand wordt geparseerd en vooral wanneer het herhaaldelijk wordt geparseerd, heeft dit invloed op de buildtijd.
Build Insights biedt analyses in de weergave Opgenomen bestanden , waarmee u de impact van het parseren #include van bestanden in uw project kunt vaststellen. Het geeft de tijd weer die nodig is om elk headerbestand te parseren en een weergave van de relaties tussen headerbestanden.
In dit artikel leert u hoe u de Build Insights Inbegrepen Bestanden en Include Tree weergaven gebruikt om de duurste headerbestanden om te parseren te identificeren en hoe u de buildtijd kunt optimaliseren door een vooraf gecompileerd headerbestand aan te maken.
Buildopties instellen
Voordat u Build Insights-gegevens verzamelt, stelt u de buildopties in voor het type build dat u wilt meten. Als u zich bijvoorbeeld zorgen maakt over de buildtijd voor x64-foutopsporing, stelt u de build in voor foutopsporing en x64:
Kies Debug in de vervolgkeuzelijst Oplossingsconfiguraties.
Kies x64 in de vervolgkeuzelijst Oplossingsplatformen.
De Oplossingsconfiguratie vervolgkeuzelijst wordt weergegeven. Het bevat opties voor foutopsporing, release en Configuration Manager. De vervolgkeuzelijst Solution Platform is ingesteld op x64.
Build Insights uitvoeren
Voer Build Insights uit in een project van uw keuze en gebruik de Debug-buildopties die in de vorige sectie zijn ingesteld door in het hoofdmenu Build>Run Build Insights op het <projectnaam>>Rebuild te kiezen. U kunt ook met de rechtermuisknop op een project klikken in Solution Explorer en Uitvoeren Build Insights>Rebuild kiezen. Kies Opnieuw opbouwen in plaats van Build om de bouwtijd voor het hele project te meten en niet alleen voor de enkele bestanden die nu misschien vuil zijn.
Wanneer de build is voltooid, wordt een ETL-bestand (Event Trace Log) geopend. Deze wordt opgeslagen in de map waarnaar wordt verwezen door de Windows-omgevingsvariabele TEMP . De gegenereerde naam is gebaseerd op de verzamelingstijd.
Opgenomen bestanden weergeven
Het traceringsbestand toont de buildtijd, die voor dit voorbeeld 16.404 seconden was. De diagnostische sessie is de totale tijd die nodig is om de Build Insights-sessie uit te voeren. Kies het tabblad Opgenomen bestanden .
In deze weergave ziet u de tijd die is besteed aan het verwerken van #include bestanden.
In de kolom bestandspad zijn verschillende bestanden met een brandpictogram gemarkeerd omdat ze meer dan 10% van de buildtijd in beslag nemen om te parseren. winrtHeaders.h is het grootste bestand met 8.581 seconden ofwel 52,3% van de totale bouwtijd van 16,404 seconden.
In de kolom Bestandspad hebben sommige bestanden een brandpictogram ernaast om aan te geven dat ze 10% of meer van de buildtijd in beslag nemen.
De kolom Time [sec, %] laat zien hoe lang het duurde om elke functie te compileren tijdens de wandklokverantwoordelijkheidstijd (WCTR). Deze metrische waarde distribueert de tijd van de wandklok die nodig is om bestanden te parseren op basis van het gebruik van parallelle threads. Als twee verschillende threads bijvoorbeeld twee verschillende bestanden tegelijk parseren binnen een periode van één seconde, wordt de WCTR van elk bestand vastgelegd als 0,5 seconden. Dit weerspiegelt het proportionele aandeel van elk bestand van de totale compilatietijd, rekening houdend met de resources die tijdens parallelle uitvoering worden verbruikt. WCTR biedt dus een betere meting van de impact die elk bestand heeft op de totale buildtijd in omgevingen waar meerdere compilatieactiviteiten tegelijkertijd plaatsvinden.
In de kolom Aantal parseren ziet u hoeveel tijd het headerbestand is geparseerd.
Het eerste headerbestand dat in deze lijst is gemarkeerd, heeft 8.581 seconden nodig van de totale buildtijd van 16.404 seconden, oftewel 52,3% van de buildtijd. De volgende duurste is Windows.UI.Xaml.Interop.h, en dan Windows.Xaml.h.
Als u wilt zien welk bestand bevat winrtHeaders.h, klikt u op de punthaak ernaast. De kolom Aantal parseren kan handig zijn door aan te wijzen hoe vaak een headerbestand is opgenomen in andere bestanden. Misschien is een headerbestand meerdere keren opgenomen, wat een teken kan zijn dat het een goede kandidaat is voor een vooraf gecompileerd headerbestand of herstructureren.
In de kolom Vertaaleenheid ziet u welk bestand werd verwerkt toen het opgenomen bestand werd verwerkt. In dit voorbeeld is winrtHeaders.h opgenomen terwijl Grapher.cpp werd gecompileerd.
Een voorbeeld van een ETL-bestand met de insluitingsbestanden voor een voorbeeldproject. In de kolom met bestandspaden is winrtHeaders.h geselecteerd en uitgevouwen. Het bouwen duurt 8,219 seconden, wat 50,1% van de totale bouwtijd beslaat. Het onderliggende knooppunt is Grapher.cpp, dat ook wordt vermeld als de vertaaleenheid.'
De kolom vertaaleenheden kan helpen om te bepalen welk bestand wordt gecompileerd in gevallen waarin een headerbestand vaak wordt opgenomen en u wilt weten waar dat het meest gebeurt.
We weten dat het winrtHeaders.h duur is om te parseren, maar we kunnen meer leren.
Boomstructuurweergave opnemen
In deze weergave zijn de onderliggende knooppunten de bestanden die tot het bovenliggende knooppunt behoren. Dit kan u helpen inzicht te krijgen in de relaties tussen headerbestanden en mogelijkheden te identificeren om het aantal keren dat een headerbestand wordt geparseerd te verminderen.
Selecteer het tabblad Structuur opnemen in het ETL-bestand om de weergave Structuur opnemen weer te geven:
Toont de inclusieboom voor een project. In de kolom bestandspad wordt elk bestand met andere bestanden weergegeven, samen met het aantal bestanden dat het bevat en de tijd om het te parseren.
In deze weergave toont de kolom Bestandspad elk bestand dat andere bestanden bevat. Het aantal inclusies geeft aan hoeveel bestanden dit headerbestand omvat. De tijd voor het parseren van dit bestand wordt vermeld en wanneer dit wordt uitgevouwen, wordt de tijd vermeld om elk afzonderlijk headerbestand te parseren dat dit headerbestand bevat.
Eerder zagen we dat parseren winrtHeaders.h tijdrovend is. In het tekstvak Bestanden filteren, kunnen we, als we winrtHeaders.h invoeren, de weergave filteren zodat alleen de vermeldingen worden weergegeven die winrtHeaders.h in de naam bevatten. Door op het pijltje naast winrtHeaders.h te klikken, wordt weergegeven welke bestanden het bevat:
De kolom bestandspad bevat elk bestand dat andere bestanden bevat, samen met het aantal bestanden dat het bevat en de tijd die nodig was om het te parseren. winrtHeaders.h is geselecteerd en uitgevouwen om de bestanden weer te geven die het bevat. Windows.UI.Xaml.Interop.h is een van die bestanden en wordt uitgebreid om Windows.UI.Xaml.Interop.h te tonen, die is uitgebreid om de koptekstbestanden die het bevat weer te geven.
We zien dat winrtHeaders.h het omvat Windows.UI.Xaml.Interop.h. Onthoud in de weergave Opgenomen bestanden dat dit ook tijdrovend was om te parseren. Klik op de chevron naast Windows.UI.Xaml.Interop.h om te zien dat het Windows.UI.Xaml.h bevat, wat 21 andere header-bestanden bevat, waarvan er twee ook op de hotlist staan.
Nadat we enkele van de duurste headerbestanden om te parseren hebben geïdentificeerd en hebben gezien dat winrtHeaders.h verantwoordelijk is voor het binnenhalen ervan, suggereert dit dat we een vooraf gecompileerde header kunnen gebruiken om het opnemen van winrtHeaders.h sneller te maken.
Compilatietijd verbeteren met vooraf gecompileerde headers
Omdat we uit de weergave Opgenomen bestanden weten dat het parseren ervan veel tijd kost, en omdat we uit de winrtHeaders.h zien dat meerdere andere headerbestanden bevat die ook tijdrovend zijn om te parseren, bouwen we een winrtHeaders.h (PCH) om dat te versnellen door deze slechts één keer naar een PCH te parseren.
We voegen een pch.h toe om winrtHeaders.h op te nemen, wat er als volgt uitziet:
#ifndef CALC_PCH
#define CALC_PCH
#include <winrtHeaders.h>
#endif // CALC_PCH
PCH-bestanden moeten worden gecompileerd voordat ze kunnen worden gebruikt, dus voegen we een bestand toe aan het project, willekeurig benoemd pch.cpp, dat omvat pch.h. Deze bevat één regel:
#include "pch.h"
Vervolgens stellen we ons project in op het gebruik van de PCH. Dat wordt gedaan in projecteigenschappen via C/C++>Vooraf gecompileerde headers en het instellen van vooraf gecompileerde headers voor gebruik (/Yu) en vooraf gecompileerd headerbestand op pch.h.
Vooraf gecompileerde header is ingesteld op: Gebruik (/Yu). Het vooraf gecompileerde headerbestand is ingesteld op pch.h.
Als u de PCH wilt gebruiken, nemen we deze op als de eerste regel in de bronbestanden die gebruikmaken van winrtHeaders.h. Deze moet worden geleverd voordat andere bestanden zijn opgenomen. Voor het gemak kunnen we de projecteigenschappen wijzigen zodat ze aan het begin van elk bestand in de oplossing worden opgenomen pch.h door de projecteigenschap in te stellen: C/C++>Advanced>Forced Include File naar pch.h:
Geforceerd include-bestand is ingesteld op pch.h.
Omdat de PCH bevat winrtHeaders.h, kunnen we verwijderen winrtHeaders.h uit alle bestanden die deze momenteel bevatten. Het is niet strikt noodzakelijk omdat de compiler zich realiseert dat deze winrtHeaders.h al is opgenomen en deze niet opnieuw parseert. Sommige ontwikkelaars behouden het #include bronbestand liever voor duidelijkheid, of als de PCH waarschijnlijk wordt geherstructureerd en dat headerbestand mogelijk niet meer bevat.
De wijzigingen testen
We maken het project eerst schoon om zeker te zijn dat we dezelfde bestanden als voorheen vergelijken. Als u slechts één project wilt opschonen, klikt u met de rechtermuisknop op het project in Solution Explorer en kiest u Alleen project>Alleen opschonen van <projectnaam>.
Omdat dit project nu gebruikmaakt van een vooraf gecompileerde header (PCH), willen we de tijd die nodig is om de PCH te bouwen niet meten, omdat dat maar één keer gebeurt. Dit doen we door het pch.cpp bestand te laden en Ctrl+F7 te kiezen om alleen dat bestand te bouwen. We kunnen dit bestand ook compileren door met de rechtermuisknop te pch.cpp klikken in Solution Explorer en te Compilekiezen.
Nu voeren we Build Insights opnieuw uit in de Solution Explorer door met de rechtermuisknop op het project te klikken en te kiezen voor Alleen project>, Build Insights uitvoeren op bouwen. U kunt ook met de rechtermuisknop op een project in Solution Explorer klikken en Build Insights>Build uitvoeren kiezen. We willen deze keer niet opnieuw opbouwen , omdat hiermee de PCH wordt herbouwd, die we niet willen meten. We hebben het project eerder opgeschoond, wat betekent dat een normale build alle projectbestanden compileert die we willen meten.
Wanneer de ETL-bestanden worden weergegeven, zien we dat de buildtijd is gegaan van 16.404 seconden tot 6,615 seconden. Zet winrtHeaders.h het filtervak in en er wordt niets weergegeven. Dit komt doordat de tijd die is besteed aan het parseren ervan nu verwaarloosbaar is omdat deze wordt opgehaald door de vooraf gecompileerde header.
In dit voorbeeld worden vooraf gecompileerde headers gebruikt omdat ze een algemene oplossing zijn voor C++20. Vanaf C++20 zijn er echter andere, snellere, minder broose manieren om headerbestanden op te nemen, zoals header-eenheden en modules. Voor meer informatie, zie Koptekst-eenheden, modules en vooraf gecompileerde headers vergelijken.
Navigeren tussen weergaven
Er zijn enkele navigatiefuncties voor zowel opgenomen bestanden als structuurweergaven :
- Dubbelklik op een bestand (of druk op Enter) in de Inbegrepen bestanden of Insluitboom om de broncode van dat bestand te openen.
- Klik met de rechtermuisknop op een koptekstbestand om dat bestand in de andere weergave te vinden. Klik bijvoorbeeld in de weergave van Inbegrepen bestanden, klik met de rechtermuisknop op
winrtHeaders.hen kies Zoeken in includeboom om deze te zien in de includeboomweergave.
U kunt ook met de rechtermuisknop op een bestand klikken in de weergave Includeboom om naar het bestand te gaan in de weergave Opgenomen bestanden.
Tips
- U kunt bestand>opslaan als het ETL-bestand op een meer permanente locatie om een record van de buildtijd te bewaren. Vervolgens kunt u deze vergelijken met toekomstige builds om te zien of uw wijzigingen de buildtijd verbeteren.
- Als u per ongeluk het venster Build Insights sluit, opent u het opnieuw door het
<dateandtime>.etlbestand in uw tijdelijke map te vinden. DeTEMPWindows-omgevingsvariabele biedt het pad van de map met tijdelijke bestanden. - Als u de Build Insights-gegevens wilt bekijken met Windows Performance Analyzer (WPA), klikt u op de knop Openen in WPA in de rechterbenedenhoek van het ETL-venster.
- Sleep kolommen om de volgorde van de kolommen te wijzigen. U kunt bijvoorbeeld liever de kolom Tijd verplaatsen naar de eerste kolom. U kunt kolommen verbergen of uitschakelen door met de rechtermuisknop op de kolomkop te klikken en de kolommen die u niet wilt zien uit te schakelen.
- De opgenomen bestanden en structuurweergaven bieden een filtervak om een headerbestand te vinden waarin u geïnteresseerd bent. Er wordt gezocht naar gedeeltelijke overeenkomsten met de naam die u opgeeft.
- Soms is de parseringstijd die voor een headerbestand is gerapporteerd, afhankelijk van het bestand dat het bevat. Dit kan worden veroorzaakt door de interactie tussen verschillende
#defines die van invloed zijn op welke delen van de header worden uitgevouwen, bestandscache en andere systeemfactoren. - Als u vergeet wat de weergave Opgenomen bestanden of de Includeboom probeert te tonen, houdt u de muisaanwijzer boven het tabblad om een tooltip te zien die de weergave beschrijft. Als u bijvoorbeeld met de muis over het tabblad Structuur opnemen gaat, zegt de tooltip: 'Weergave die statistieken toont voor elk bestand, waarbij de onderliggende knooppunten de bestanden zijn die door het bovenliggende knooppunt zijn opgenomen'.
- Mogelijk ziet u gevallen (zoals
Windows.h) waarbij de geaggregeerde duur van alle tijden voor een headerbestand langer is dan de duur van de hele build. Wat er gebeurt, is dat headers tegelijkertijd worden geparseerd op meerdere threads. Als twee threads tegelijk één seconde besteden aan het parseren van een headerbestand, is dat 2 seconden aan buildtijd, zelfs als er slechts één seconde tijd van de wandklok voorbij is. Zie verantwoordelijkheidstijd voor wandklok (WCTR) voor meer informatie.
Probleemoplossingsproces
- Als het venster Build Insights niet wordt weergegeven, voert u een herbouw uit in plaats van een build. Het venster Build Insights wordt niet weergegeven als er niets daadwerkelijk wordt gebouwd; dit kan het geval zijn als er geen bestanden zijn gewijzigd sinds de laatste build.
- Als een headerbestand waarin u geïnteresseerd bent, niet wordt weergegeven in de Inbegrepen bestanden of Inbegrepen structuren, is het mogelijk niet gebouwd, of is de buildtijd niet significant genoeg om te worden vermeld.
Zie ook
Tips en trucs voor inzichten bouwen
Header-eenheden, modules en voorgecompileerde headers vergelijken
Inzichten bouwen in Visual Studio-video - Pure Virtual C++ 2023
Snellere C++-builds, vereenvoudigd: een nieuwe metrische waarde voor tijd
Problemen met functie-inlining tijdens de bouwtijd oplossen
vcperf en Windows Performance Analyzer