Dela via


Felsöka header-filens påverkan på byggtiden

Använd vyerna Inkluderade filer i Build Insights och Inkluderingsträd för att felsöka effekten av #include filer på byggtider för C och C++.

Förutsättningar

  • Visual Studio 2022 17.8 eller senare.
  • C++ Build Insights är aktiverat som standard om du installerar antingen skrivbordsutvecklingen med C++-arbetsbelastningen med hjälp av Installationsprogrammet för Visual Studio:

Skärmbild av Visual Studio Installer med skrivbordsutvecklingen med C++-arbetsbelastningen vald.

Listan över installerade komponenter visas. C++ Build Insights är markerat och valt, vilket innebär att det är installerat.

Eller spelutvecklingen med C++-arbetsbelastning:

Skärmbild av Visual Studio Installer med arbetsuppgiftspaketet för spelutveckling med C++ valt.

Listan över installerade komponenter visas. C++ Build Insights är markerat och valt, vilket innebär att det är installerat.

Översikt

Build Insights, som nu är integrerat i Visual Studio, hjälper dig att optimera dina byggtider – särskilt för stora projekt som trippel-A-spel. När en stor rubrikfil parsas, och särskilt när den parsas upprepade gånger, påverkas byggtiden.

Build Insights tillhandahåller analys i vyn Inkluderade filer , som hjälper dig att diagnostisera effekten av att parsa #include filer i projektet. Den visar den tid det tar att parsa varje rubrikfil och en vy över relationerna mellan huvudfilerna.

I den här artikeln lär du dig hur du använder vyerna Build Insights Included Files och Include Tree för att identifiera de dyraste huvudfilerna att parsa och hur du optimerar byggtiden genom att skapa en fördefinierad huvudfil.

Ange byggalternativ

Innan du samlar in Build Insights-data anger du byggalternativen för den typ av bygge som du vill mäta. Om du till exempel är orolig för byggtiden för x64-felsökning anger du versionen för Felsökning och x64:

  • I listrutan Lösningskonfigurationer väljer du Felsök.

  • I listrutan Lösningsplattformar väljer du x64.

    Skärmbild av listrutorna för lösningskonfiguration.

    Listrutan Lösningskonfiguration visas. Den har alternativ för Felsökning, Version och Configuration Manager. Listrutan Lösningsplattform är inställd på x64.

Kör Build Insights

På ett valfritt projekt, och med hjälp av de felsökningsalternativ som angavs i föregående avsnitt, kör Build Insights genom att välja i huvudmenyn Skapa>Kör Build Insights på <projektnamnet>>Bygg om. Du kan också högerklicka på ett projekt i Solution Explorer och välja Kör Build Insights>Rebuild. Välj Återskapa i stället för Skapa för att mäta byggtiden för hela projektet och inte bara för de få filer som kan vara smutsiga just nu.

Skärmbild av huvudmenyn med Run Build Insights on Selection > Återskapa vald.

När bygget är klart öppnas en ETL-fil (Event Trace Log). Den sparas i mappen som pekas på av Miljövariabeln Windows TEMP . Det genererade namnet baseras på insamlingstiden.

Inkluderade filer-vy

Spårningsfilen visar byggtiden – som i det här exemplet var 16,404 sekunder. Diagnostiksessionen är den totala tid det tar att köra Build Insights-sessionen. Välj fliken Inkluderade filer .

Den här vyn visar den tid som tillbringas på att bearbeta #include-filer.

Skärmbild av den inkluderade filvyn.

I kolumnen för filsökväg markeras flera filer med en eldsymbol eftersom de tar över 10% av byggtiden att analysera. winrtHeaders.h är den största på 8,581 sekunder eller 52,3% av byggtiden på 16,404 sekunder.

I kolumnen Filsökväg har vissa filer en brandikon bredvid sig för att indikera att de tar upp 10% eller mer av byggtiden.

Kolumnen Time [sec, %] visar hur lång tid det tog att kompilera varje funktion i WCTR (Wall Clock Responsibility Time). Det här måttet distribuerar den tid det tar att parsa filer baserat på deras användning av parallella trådar. Om två olika trådar till exempel parsar två olika filer samtidigt inom en sekund, registreras varje fils WCTR som 0,5 sekunder. Detta återspeglar varje fils proportionella andel av den totala kompileringstiden, med hänsyn till de resurser som var och en förbrukas under parallell körning. WCTR ger därför ett bättre mått på vilken inverkan varje fil har på den övergripande byggtiden i miljöer där flera kompileringsaktiviteter utförs samtidigt.

Kolumnen Parsa antal visar hur många gånger rubrikfilen parsades.

Den första huvudfilen som är markerad i den här listan är winrtHeaders.h Det tar 8,581 sekunder av den totala byggtiden på 16,404 sekunder eller 52,3% av byggtiden. Den näst dyraste är Windows.UI.Xaml.Interop.h, och sedan Windows.Xaml.h.

Om du vill se vilken fil som innehåller winrtHeaders.hklickar du på sparren bredvid den. Kolumnen Parsa antal kan vara till hjälp genom att peka på hur många gånger en rubrikfil ingår i andra filer. Kanske ingår en rubrikfil flera gånger, vilket kan vara ett tecken på att den är en bra kandidat för en fördefinierad rubrikfil eller refaktorisering.

Kolumnen Översättningsenhet visar vilken fil som bearbetades när den inkluderade filen bearbetades. I det här exemplet winrtHeaders.h inkluderades när Grapher.cpp kompilerades:

Skärmbild av vyn Inkluderade filer.

Ett exempel på en ETL-fil som visar de inkluderade filerna för ett exempelprojekt. I filsökvägskolumnen markeras winrtHeaders.h och expanderas. Det tar 8,219 sekunder att skapa, vilket är 50,1% av byggtiden. Dess underordnade nod är Grapher.cpp, som också visas som översättningsenhet."

Översättningsenhetens kolumn kan hjälpa till att skilja på vilken fil som kompilerades i de fall där en rubrikfil ingår många gånger och du vill ta reda på var det händer mest.

Vi vet att det winrtHeaders.h är dyrt att parsa, men vi kan lära oss mer.

Inkludera trädvy

I den här vyn är barnnoderna de filer som ingår i den överordnade noden. Detta kan hjälpa dig att förstå relationerna mellan huvudfiler och identifiera möjligheter att minska antalet gånger en rubrikfil parsas.

Välj fliken Inkludera träd i ETL-filen för att se vyn Inkludera träd:

Skärmbild av vyn Inkludera träd.

Visar inkluderingsträdet för ett projekt. I kolumnen filsökväg visas varje fil som innehåller andra filer, tillsammans med hur många filer den innehåller och tiden för att parsa den.

I den här vyn visar kolumnen Sökväg varje fil som innehåller andra filer. Inkluderingsantal listar hur många filer som denna headerfil inkluderar. Tiden för att parsa den här filen visas, och när den expanderas visas tiden för att parsa varje enskild rubrikfil som den här rubrikfilen innehåller.

Tidigare såg vi att parsning winrtHeaders.h är tidskrävande. Om vi anger i textrutan winrtHeaders.h kan vi filtrera vyn till endast de poster som innehåller winrtHeaders.h i namnet. Om du klickar på sparren bredvid winrtHeaders.h visas vilka filer den innehåller:

Skärmbild av expanderad inkluderingsträdsvy.

Kolumnen filsökväg visar varje fil som innehåller andra filer, tillsammans med hur många filer den innehåller och den tid det tog att parsa den. winrtHeaders.h har valts och expanderats för att visa de filer som den innehåller. Windows.UI.Xaml.Interop.h är en av dessa filer och expanderas för att visa Windows.UI.Xaml.Interop.h som expanderas för att visa huvudfilerna som den innehåller.

Vi ser att winrtHeaders.h inkluderar Windows.UI.Xaml.Interop.h. Kom ihåg från vyn Inkluderade filer att detta också var tidskrävande att parsa. Klicka på chevronen bredvid Windows.UI.Xaml.Interop.h för att se att den innehåller Windows.UI.Xaml.h, som inkluderar 21 andra header-filer, varav två också finns med på den populära listan.

Genom att identifiera några av de dyraste huvudfilerna att parsa, och att se att winrtHeaders.h är ansvarig för att ta in dem, tyder på att vi kan använda en förkompilerad rubrikfil för att göra snabbare inkludering av winrtHeaders.h.

Förbättra byggtiden med förkompilerade rubriker

Eftersom vi vet från vyn Inkluderade filer att det winrtHeaders.h är tidskrävande att parsa, och eftersom vi vet från vyn Inkludera träd som winrtHeaders.h innehåller flera andra huvudfiler som är tidskrävande att parsa, skapar vi en fördefinierad rubrikfil (PCH) för att påskynda det genom att bara parsa dem en gång i en PCH.

Vi lägger till en pch.h för att inkludera winrtHeaders.h, som skulle se ut så här:

#ifndef CALC_PCH
#define CALC_PCH

#include <winrtHeaders.h>

#endif // CALC_PCH

PCH-filer måste kompileras innan de kan användas, så vi lägger till en fil i projektet, godtyckligt med namnet pch.cpp, som innehåller pch.h. Den innehåller en rad:

#include "pch.h"

Sedan ställer vi in vårt projekt på att använda PCH. Detta görs i projektegenskaper via C/C++>Förkompilerade rubriker och anger förkompilerat sidhuvud till Använd (/Yu) och Förkompilerad rubrikfil till pch.h.

Skärmbild av dialogrutan projektegenskaper med inställningarna för förkompilerade rubriker öppna.

Förkompilerad rubrik är inställd på: Använd (/Yu). Den förkompilerade rubrikfilen är inställd på pch.h.

För att använda PCH inkluderar vi den som den första raden i källfilerna som använder winrtHeaders.h. Det måste komma före alla andra inkluderingsfiler. För enkelhetens skull kan vi ändra projektegenskaperna så att de inkluderas pch.h i början av varje fil i lösningen genom att ange projektegenskapen : C/C++>Avancerad tvingad>inkluderingsfil till pch.h:

Skärmbild av dialogrutan projektegenskaper med avancerade inställningar öppna.

Tvingad inkluderingsfil är inställd på pch.h.

Eftersom PCH innehåller winrtHeaders.hkan vi ta bort winrtHeaders.h från alla filer som för närvarande innehåller den. Det är inte absolut nödvändigt eftersom kompilatorn inser att den winrtHeaders.h redan ingår och inte parsar den igen. Vissa utvecklare föredrar att behålla #include i källfilen för tydlighetens skull, eller om PCH sannolikt kommer att omstruktureras och kanske inte längre innehåller huvudfilen.

Testa ändringarna

Först rensar vi projektet för att se till att vi jämför att skapa samma filer som tidigare. Om du bara vill rensa ett projekt högerklickar du på projektet i Solution Explorer och väljer Endast> ProjektRensa endast <prj-namn>.

Eftersom det här projektet nu använder en fördefinierad rubrik (PCH) vill vi inte mäta hur mycket tid det tar att skapa PCH eftersom det bara sker en gång. Det gör vi genom att läsa in pch.cpp filen och välja Ctrl+F7 för att skapa just den filen. Vi kan också kompilera den här filen genom att högerklicka på pch.cpp i 'Solution Explorer' och välja Compile.

Nu kör vi Build Insights igen i Solution Explorer genom att högerklicka på projektet och välja Project Only>Run Build Insights on Build. Du kan också högerklicka på ett projekt i Solution Explorer och välja Kör Build Insights>Build. Vi vill inte återskapa den här gången eftersom det återskapar PCH, som vi inte vill mäta. Vi rensade projektet tidigare, vilket innebär att en normal version kompilerar alla projektfiler som vi vill mäta.

När ETL-filerna visas ser vi att byggtiden gick från 16,404 sekunder till 6,615 sekunder. Placera winrtHeaders.h i filterrutan så visas ingenting. Det beror på att den tid som ägnas åt att parsa den nu är försumbar eftersom den hämtas in av den förkompilerade headern.

Skärmbild av fönstret Inkludera träd i spårningsfilen. winrtHeaders visas inte längre.

I det här exemplet används förkompilerade rubriker eftersom de är en vanlig lösning före C++20. Men från och med C++20 finns det andra, snabbare, mindre spröda, sätt att inkludera huvudfiler – till exempel rubrikenheter och moduler. Mer information finns i Jämför rubrikenheter, moduler och förkompilerade rubriker.

Det finns några navigeringsfunktioner för både de inkluderade filerna och inkluderingsträdvyer :

  • Dubbelklicka på en fil (eller tryck på Retur) i antingen Inkluderade filer eller Inkludera träd för att öppna källkoden för filen.
  • Högerklicka på en rubrikfil för att hitta filen i den andra vyn. I vyn Inkluderad filhögerklickar du till exempel på winrtHeaders.h och väljer Sök i Inkludera träd för att se den i vyn Inkludera träd .

Skärmbild av en högerklicka på en fil i vyn Inkluderade filer. Menyalternativet Visa i Inkludera trädvy är markerat.

Du kan också högerklicka på en fil i vyn Inkludera träd för att hoppa till den i vyn Inkluderade filer .

Råd

  • Du kan Arkiv>Spara som ETL-filen till en mer permanent plats för att spara en kopia av byggtiden. Du kan sedan jämföra det med framtida versioner för att se om dina ändringar förbättrar byggtiden.
  • Om du oavsiktligt stänger fönstret Build Insights öppnar du det igen genom att hitta filen i den <dateandtime>.etl tillfälliga mappen. Miljövariabeln TEMP Windows innehåller sökvägen till mappen temporära filer.
  • Om du vill ta en titt på Build Insights-data med Windows Performance Analyzer (WPA) klickar du på knappen Öppna i WPA längst ned till höger i ETL-fönstret.
  • Dra kolumner för att ändra ordningen på kolumnerna. Du kanske till exempel föredrar att flytta kolumnen Tid till den första kolumnen. Du kan dölja kolumner genom att högerklicka på kolumnrubriken och avmarkera de kolumner som du inte vill se.
  • Vyerna Inkluderade filer och Inkludera träd innehåller en filterruta för att hitta en rubrikfil som du är intresserad av. Den matchar delvis det namn som du anger.
  • Ibland skiljer sig den parsningstid som rapporteras för en rubrikfil beroende på vilken fil som innehåller den. Detta kan bero på samspelet mellan olika #defines som påverkar vilka delar av huvud som expanderas, filcache och andra systemfaktorer.
  • Om du glömmer vad vyn Inkluderade filer eller Inkludera träd försöker visa dig hovrar du över fliken för att se en knappbeskrivning som beskriver vyn. Om du till exempel hovrar över fliken Inkludera träd står det i knappbeskrivningen: "Visa som visar statistik för inkluderingar för varje fil där barnnoderna är de filer som inkluderas i den överordnade noden."
  • Du kan se fall (till exempel Windows.h) där den aggregerade varaktigheten för alla varaktigheter för en rubrikfil är längre än varaktigheten för hela builden. Det som händer är att rubrikerna tolkas på flera trådar samtidigt. Om två trådar samtidigt ägnar en sekund åt att parsa en header-fil är det 2 sekunders byggtid trots att bara en sekund av väggklockan har gått. Mer information finns i väggklockans ansvarstid (WCTR).

Felsökning

  • Om fönstret Build Insights inte visas, gör du en ombyggnad i stället för en bygg. Fönstret Build Insights visas inte om ingenting faktiskt byggs. vilket kan vara fallet om inga filer har ändrats sedan den senaste versionen.
  • Om en rubrikfil som du är intresserad av inte visas i vyn Inkluderade filer eller Inkludera träd har den antingen inte skapats eller så är dess byggtid inte tillräckligt betydande för att visas.

Se även

Tips och tricks för Att skapa insikter
Jämför rubrikenheter, moduler och förkompilerade rubriker
Skapa insikter i Visual Studio-video – Pure Virtual C++ 2023
Snabbare C++-versioner, förenklat: ett nytt mått för tid
Felsöka funktionsinslinering vid byggtid
vcperf och Windows Performance Analyzer