13 KiB
Profiling the Swift Compiler on Windows
This document describes Windows profiling tools from the angle of profiling the Swift compiler itself. The information is mostly general purpose, but specifics relevant to other applications aren't considered.
The recommended approach when you need detailed function and I/O operation-level profiling of the Swift compiler on Windows is to use Event Tracing for Windows (ETW). This includes using Windows Performance Recorder (WPR) to collect profiling data in ETL format and then Windows Performance Analyzer (WPA) to analyze it. For specific analyses not available in WPA, you will also be able to use xperf.exe to convert a binary ETL file to a text format for analysis by another program. We also discuss a couple of alternatives which may in certain cases be easier to use or provide specific data of interest: Visual Studio (the full IDE, not VS Code) and Intel VTune.
The document is organized as follows:
- Recommended: Using Event Tracing for Windows (ETW) to profile Swift compiler runs
- Alternative: Using Visual Studio to profile Swift compiler runs
- Alternative: Using VTune to profile Swift compiler runs
- Reference: Survey of Windows profiling tools
- Reference: Building the Swift toolchain for Windows with debugging symbols
Recommended: Using Event Tracing for Windows (ETW) to profile Swift compiler runs
- Make sure you have a build of the Swift toolchain with PDB format debug symbols. One approach is to follow Building the Swift toolchain for Windows with debugging symbols.
- Use
wpr(Windows Performance Recorder) or a wrapper script like utils/windows-profiling-tools/RunProfiler.ps1 to collect a.etlfile (event trace log).- If you are using a custom-built Swift toolchain, set environment variables as instructed in WindowsQuickStart.md.
- Example usage of
RunProfiler.ps1:...\RunProfiler.ps1 -TracePath C:\Temp\program.etl -Target swiftc program.swift. Hereprogram.swiftjust serves as a workload for running the compiler. Different parts of the compiler will naturally be exercised more or less depending on the program. - Instead of running
swiftcdirectly, you can instead call a build system likeswift buildorcmaketo build a larger program. Longer compilations will result in larger.etlfiles. Try a small program first, to see what the.etlfile collection and analysis process is like (including the size of.etlfiles).
- Run
wpa.exe <path\to\trace.etl>to load the.etlfile into WPA and analyze it.- On the left, double click on the view you're interested in. Some useful ones include "Computation > CPU Usage (Sampled)," "System Activity > Processes," and "Storage > File I/O > Activity by Process, Thead, Type."
- Sort by Process name and select other related processes you may be interested in like
swift.exe. Then right click on the selected processes and choose "Filter To Selection" to hide all other processes. Alternatively, right click on the table header, select "Edit Filters," and enter "Process Name" constraints. - Go to Trace > Configure Symbol Paths. It will open a Configure Symbols dialog. Add
S:\Program Files\Swift\Runtimes\0.0.0\usr\binandS:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\binthe list in the Paths tab. This enables WPA to find PDB files for our EXEs and DLLs. You shouldn't have to reconfigure this every time you run WPA. - Make sure Trace > Load Symbols is selected. If it's unselected, it will likely take some time to load symbols once you select it.
- The Stack column of the process list should now show function symbols as you drill down into execution times for various parts of the call stack. If you're in a view that doesn't include Stack or another column you want, right click on the table header and select "More Columns..." > the column view you want or right click the table header and select "Open View Editor..." for more detailed configuration.
Alternative: Using Visual Studio to profile Swift compiler runs
Visual Studio (the full IDE, not VS Code) has a built-in profiler that can profile arbitrary executables without requiring a Visual Studio solution or project. This includes the Swift compiler, provided it is built with PDB format debug symbols. By default, Visual Studio's profiler only records profiling data for the directly invoked process, not child processes. This makes it a less than ideal choice for top level Swift builds that invoke many child processes, but can still be useful if you have a specific swift-frontend.exe command you would like to profile.
Assuming you want to profile swiftc.exe's call to swift-frontend.exe run on an input source file S:\Temp\hello.swift:
- On the command line, run
swiftc.exe -v hello.swift(for example). This will give you aswift-frontend.execommand thatswiftc.execalls. - Open Visual Studio without any files/project.
- Debug > Performance Profiler...
- Change Target > Executable
- Path to executable:
S:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\bin\swift-frontend.exe - Command line options: (as output in step (1) above).
- Working directory:
S:\Temp - Environment Variables: see "Using the Toolchain" in WindowsQuickStart.md.
- Path to executable:
- Click Ok, select "CPU Usage," click Start.
- When the run is done, Visual Studio will present you with a GUI with lists of the functions that take the most time as well as hot traces, which you can explore further.
Alternative: Using VTune to profile Swift compiler runs
Intel VTune supports profiling using Intel processors' Performance Monitoring Unit (PMU), which provides hardware-level performance counters. It's available as an integrated GUI application as well as a standalone command line executable (vtune.exe) that can collect performance logs to be analyzed in the GUI. We'll discuss the GUI workflow here.
- Download VTune for Windows from Intel and install it on a Windows computer with an Intel processor. The first time you launch VTune, a helpful walkthrough tutorial is available. After that:
- On the Welcome tab, click "Configure Analysis..." and configure it as follows:
-
Where: Local Host (default)
-
What: Launch Application (default)
-
Application: for example,
S:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe -
Application parameters: for example,
hello.swift -
Uncheck "Use application directory as working directory"
-
Working directory: for example,
S:\Temp -
Advanced >
- User-defined environment variables: see "Using the Toolchain" in WindowsQuickStart.md.
- Make sure "Analyze child processes" is checked (it is by default)
- Duration time estimate: Under 1 minute
- Store result in (and create link file to) another directory:
C:\Users\%USER%\Documents\VTune\Projects\swift_hello(note: manually fill in your%USER%)
-
How: Select what you would like to profile. Hotspots will tell you where most of the time is spent in the code.
-
Click the "Search Sources/Binaries" button (folder with a magnifying glass) and add the following search directories:
S:\Program Files\Swift\Runtimes\0.0.0\usr\binS:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\bin
-
Click the "Start" button ("play" button style triangle above). If you would prefer to run
vtune.exefrom the command line, click the ">_" button seen above to get the command to run.
-
- After profiling
swiftc.exe hello.swiftexits, you will be taken to an analysis tab to view the results, which include hot traces and time consuming functions.
Reference: Survey of Windows profiling tools
This section describes Windows profiling tools that can be used with the Swift compiler and the relationships between them.
- WPT = Windows Performance Toolkit is a collection of tools & infrastructure for profiling from Microsoft. Includes the WP* and XPerf* tools below.
- ETW = Event Tracing for Windows is the OS-level feature for collecting application and kernel performance event traces. Microsoft/Windows Profiler tools drive ETW to collect events.
- Performance event recorders:
- WPR = Windows Performance Recorder lets you start and stop an ETW session by running
wpr.exe. Collects profiling data for all running processes and saves it to a.etlfile. See utils/windows-profiling-tools/RunProfiler.ps1 for a PowerShell script that runs WPR for the duration of a specified command invocation. - XPerf is an older, lower level equivalent of WPR. It supports a few obscure ETW settings not exposed by WPR, but WPR is recommended if meets your needs.
- Visual Studio also supports profiling
.exes that don’t have to be part of a Visual Studio solution/project, starting by opening VS without any files/project, then going to Debug > Performance Profiler... By default, it only profiles the initial process launched from the.exe, not child processes. - Intel VTune supports profiling using Intel processors’ Performance Monitoring Unit (PMU) rather than ETW. It’s available as an integrated GUI application as well as a standalone command line executable that can collect performance logs to be analyzed in the GUI.
- WPR = Windows Performance Recorder lets you start and stop an ETW session by running
- File formats:
.etlis the output binary event log file format produced by tools like WPR and XPerf. There are also a command line tools includingxperf.exeandtracerpt.exethat can be used to convert an ETL file into multiple text-based formats..wprpis an XML configuration file format used to configure WPR’s operation. For example, utils/windows-profiling-tools/CpuAndWaitsWithLargeBuffers.wprp increases the in-memory buffer size that WPR configures ETW to use so as not to drop events during recording.
- Analysis GUIs:
- WPA = Windows Performance Analyzer is a GUI that lets you analyze various aspects of the performance trace data found in
.etlfiles. It can be invoked on the command line by runningwpa.exewith the.etlfile as an argument. See Using Event Tracing for Windows (ETW) to profile Swift compiler runs for how to view program profiles with symbols. - XPerfView is an older GUI for analyzing
.etlfiles that has been replaced by WPA. - Visual Studio directly displays profile results after recording a profile data from a run of a program. By default, it only shows profiles for the directly invoked program, not for subprocesses.
- Intel VTune can either directly display profile results after recording them or display profile results from a command line run of
vtune.exe(possibly run on a different host).
- WPA = Windows Performance Analyzer is a GUI that lets you analyze various aspects of the performance trace data found in
- Analysis CLIs:
wpaexport.exetakes a profile built in the WPA GUI and exports data from a.etlfile according to that profile. Note that profiles that include hierarchical lists in the GUI may only export the top levels of the hierarchy. In this case, you can reconfigure the WPA GUI view to make the list flat and then export a new profile.xperf.execan be used to operate on.etlfiles recorded with eitherwpr.exeorxperf.exeitself. Examples:- Dump all events from a
.etlfile in text format:xperf -i <INPUT>.etl -o <OUTPUT>.txt -symbols -target machine -a dumper -stacktimeshiftingwhere<INPUT>and<OUTPUT>are files of your choice with_NT_SYMBOL_PATHset in the environment to point to directories containing PDB files, e.g. in PowerShell:$env:_NT_SYMBOL_PATH="S:\b\5\bin\bin"(list all directories containing relevant PDB files, separated by semicolons)
- List execution times per function from a
.etlfile, not including the time taken by calls to other functions:xperf -i <INPUT>.etl -o <OUTPUT>.txt -symbols -a profile -detail
- Dump all events from a
Building the Swift toolchain for Windows with debugging symbols
To build the Swift compiler with PDB format debug symbols that are used by profile analysis tools like WPA or Visual Studio, follow the https://github.com/compnerd/swift-build/blob/main/docs/WindowsQuickStart.md instructions, using the following build.cmd command line (or a variant on it based on your exact needs):
S:\SourceCache\swift\utils\build.cmd -Windows -DebugInfo -SkipPackaging -WindowsSDKArchitectures x64 -CDebugFormat codeview -SwiftDebugFormat codeview
If you need to build a package that you can install on a separate Windows host, either remove -SkipPackaging in the above command, or if you've already run the above build, substitute -SkipBuild in place of -SkipPackaging.