Skip to content

Commit 52232c6

Browse files
Refine content on Profile-Guided Optimization and Google Benchmark for clarity and accuracy
1 parent fb5a2cd commit 52232c6

5 files changed

Lines changed: 37 additions & 21 deletions

File tree

content/learning-paths/laptops-and-desktops/win_profile_guided_optimisation/_index.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
---
22
title: Optimize C++ applications on Windows on Arm using Profile-Guided Optimization
33

4-
draft: true
5-
cascade:
6-
draft: true
7-
84
minutes_to_complete: 30
95

10-
who_is_this_for: This is an introductory topic for software developers who want to optimize C++ application performance on Windows on Arm using profile-guided optimization.
6+
who_is_this_for: This is an introductory topic for software developers who want to optimize C++ application performance on Windows on Arm using Profile-Guided Optimization (PGO).
117

128
learning_objectives:
139
- Microbenchmark a function using Google Benchmark.
1410
- Apply profile-guided optimization to build performance-tuned binaries for Windows on Arm.
1511
- Measure and compare performance improvements from PGO-optimized builds.
1612

1713
prerequisites:
18-
- Basic C++ understanding.
14+
- Familiarity with C++ development and compiling programs from the command line.
1915
- A Windows on Arm machine with [Visual Studio](/install-guides/vs-woa/) and the C++ desktop development tools installed.
2016

2117
author: Tom Dunkle
@@ -24,7 +20,7 @@ author: Tom Dunkle
2420
skilllevels: Introductory
2521
subjects: Performance and Architecture
2622
tools_software_languages:
27-
- C
23+
- C++
2824
- MSVC
2925
- Google Benchmark
3026
- PGO

content/learning-paths/laptops-and-desktops/win_profile_guided_optimisation/how-to-1.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Profile-Guided Optimization
2+
title: Understand Profile-Guided Optimization
33
weight: 2
44

55
### FIXED, DO NOT MODIFY
@@ -18,11 +18,11 @@ This approach identifies frequently executed paths (known as "hot" paths) and op
1818

1919
PGO enables several compiler optimizations that aren't possible with static analysis alone.
2020

21-
The compiler arranges frequently executed code together in memory through code layout optimization, which improves instruction cache utilization and reduces branch mispredictions. Instead of using heuristics for inlining decisions, the compiler inlines functions based on actual call frequency and execution patterns from your profiling data.
21+
Code layout optimization arranges frequently executed code together in memory, improving instruction cache utilization and reducing branch mispredictions. Instead of using heuristics for inlining decisions, the compiler inlines functions based on actual call frequency and execution patterns from your profiling data.
2222

2323
For C++ virtual functions, PGO can identify the most common call targets and optimize or devirtualize those paths. The compiler can also eliminate dead code by optimizing differently or removing code paths that never execute in your profiling runs.
2424

25-
For example, if your application has an error handling path that rarely executes, PGO ensures the compiler doesn't optimize for that path at the expense of your main execution flow. The result is typically 5-15% performance improvement, though gains vary by application.
25+
If your application has an error handling path that rarely executes, PGO ensures the compiler doesn't optimize for that path at the expense of your main execution flow. Performance improvements typically range from 5-15%, though results vary by workload and architecture.
2626

2727
## When should you use Profile-Guided Optimization?
2828

@@ -39,3 +39,7 @@ Your profiling data must accurately represent typical usage scenarios. If it doe
3939
Additionally, the process requires extra build steps, which can increase compile times for large codebases. Use PGO on performance-critical sections that are heavily influenced by actual runtime behavior.
4040

4141
PGO might not be ideal for early-stage development or applications with highly variable or unpredictable usage patterns.
42+
43+
## What you've learned and what's next
44+
45+
You now understand what PGO is, how it improves performance through code layout and inlining optimizations, and when to apply it. In the next section, you'll learn about Google Benchmark, the tool you'll use to measure these performance improvements.

content/learning-paths/laptops-and-desktops/win_profile_guided_optimisation/how-to-2.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ Before you start working with Profile-Guided Optimization, you need to understan
1010

1111
Google Benchmark is a C++ library specifically designed for microbenchmarking, which means measuring the performance of small code snippets with high accuracy. Microbenchmarking helps you identify bottlenecks and optimize critical sections, especially in performance-sensitive applications.
1212

13-
Google Benchmark simplifies this process by providing a framework that manages iterations, times execution, and performs statistical analysis. This lets you focus on the code being measured, rather than writing test code or trying to prevent unwanted compiler optimizations manually.
13+
Google Benchmark simplifies this process by providing a framework that manages iterations, times execution, and performs statistical analysis. You can focus on the code being measured, rather than writing test code or trying to prevent unwanted compiler optimizations manually.
1414

1515
To use Google Benchmark, you define a function that accepts a `benchmark::State&` parameter and iterate over it to perform the benchmarking. You register the function using the `BENCHMARK` macro and include `BENCHMARK_MAIN()` to generate the benchmark's entry point.
1616

17-
This example shows a basic benchmark that measures the time it takes to create an empty string:
17+
The following example shows a basic benchmark that measures the time it takes to create an empty string:
1818

1919
```cpp
2020
#include <benchmark/benchmark.h>
@@ -40,6 +40,6 @@ When you have multiple benchmarks, you can run a specific subset using the `--be
4040
.\benchmark_binary --benchmark_filter=BM_String.*
4141
```
4242

43-
This approach eliminates the need to repeatedly comment out lines of source code when you want to focus on specific benchmarks.
43+
Filtering eliminates the need to repeatedly comment out lines of source code when you want to focus on specific benchmarks.
4444

4545
Now that you understand how Google Benchmark works, you're ready to install it and run your first benchmark. In the next section, you'll set up your environment and use Google Benchmark with Profile-Guided Optimization to measure and improve performance.

content/learning-paths/laptops-and-desktops/win_profile_guided_optimisation/how-to-3.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ Integer division is ideal for benchmarking because it's significantly more expen
1212

1313
For this example, you'll use an Arm computer running Windows.
1414

15-
## Install the required tools
15+
## Set up your environment
16+
17+
Before you can run benchmarks, you need to install vcpkg (a C++ package manager) and Google Benchmark. This is a one-time setup step.
1618

1719
### Install vcpkg and Google Benchmark
1820

19-
Run the following commands in PowerShell:
21+
The following commands download and initialize vcpkg, create a project directory, and install Google Benchmark for Windows on Arm:
2022

2123
```console
2224
iex (iwr -useb https://aka.ms/vcpkg-init.ps1)
@@ -62,19 +64,19 @@ Open an **ARM64 Native Tools Command Prompt** from the Windows Start menu and st
6264
powershell
6365
```
6466

65-
Before compiling, set an environment variable to refer to the vcpkg installation directory:
67+
Set an environment variable to refer to the vcpkg-installed package directory for the ARM64 Windows target. This simplifies the compiler commands that follow:
6668

6769
```console
6870
$VCPKG="$HOME\pgo-benchmark\vcpkg_installed\arm64-windows"
6971
```
7072

71-
Now compile the benchmark. This command uses the MSVC compiler and links with the Google Benchmark libraries:
73+
Compile the benchmark. This command uses the MSVC compiler and links with the Google Benchmark libraries:
7274

7375
```console
7476
cl /I"$VCPKG\include" /D BENCHMARK_STATIC_DEFINE div_bench.cpp /link /LIBPATH:"$VCPKG\lib" benchmark.lib benchmark_main.lib shlwapi.lib
7577
```
7678

77-
Run the program to establish your baseline performance:
79+
Add the vcpkg binary directory to your PATH so the program can find required DLLs, then run the benchmark:
7880

7981
```console
8082
$env:PATH += ";$HOME\pgo-benchmark\vcpkg_installed\arm64-windows\bin"
@@ -99,4 +101,6 @@ Benchmark Time CPU Iterations
99101
baseDiv/1500 7.90 us 7.90 us 88512
100102
```
101103

104+
The warning appears because the Google Benchmark library was built in debug mode, but it doesn't affect the validity of the measurements for this example.
105+
102106
The baseline shows an average execution time of 7.90 microseconds. This gives you a clear starting point to measure improvement. Now that you have this baseline measurement, you're ready to apply Profile-Guided Optimization. In the next section, you'll use PGO to optimize this code and see how much faster it can run.

content/learning-paths/laptops-and-desktops/win_profile_guided_optimisation/how-to-4.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ Now that you have a baseline benchmark, you're ready to apply Profile-Guided Opt
1010

1111
## Build the instrumented binary
1212

13-
You should already have an ARM64 Native Tools Command Prompt open with PowerShell running from the previous section.
13+
Open an **ARM64 Native Tools Command Prompt** from the Windows Start menu and start PowerShell if it's not already open. If you're starting a new session, navigate to your project directory and set the `$VCPKG` environment variable again:
14+
15+
```console
16+
powershell
17+
cd $HOME\pgo-benchmark
18+
$VCPKG="$HOME\pgo-benchmark\vcpkg_installed\arm64-windows"
19+
```
1420

1521
Build the instrumented binary with the `/GENPROFILE` flag. This creates a version of your program that records how it executes:
1622

@@ -66,6 +72,12 @@ Benchmark Time CPU Iterations
6672
baseDiv/1500 2.86 us 2.86 us 244429
6773
```
6874

69-
The average execution time is reduced from 7.90 to 2.86 microseconds, which is a 64% improvement. This significant gain occurs because the profile data informed the compiler that the input divisor was consistently 1500 during the profiled runs, allowing it to apply specific optimizations that wouldn't be possible with static analysis alone.
75+
The warning appears because the Google Benchmark library was built in debug mode, but it doesn't affect the validity of the measurements.
76+
77+
The average execution time is reduced from 7.90 to 2.86 microseconds, which is a 64% improvement. This result was measured on a Windows on Arm device with Visual Studio 2022 (MSVC 17.0) using the division benchmark with a constant divisor of 1500. Your results may vary depending on your specific hardware and workload.
78+
79+
The compiler used the profile data to determine that the divisor was consistently 1500, enabling optimizations that wouldn't be possible with static analysis alone.
80+
81+
## What you've accomplished
7082

71-
You've successfully used Profile-Guided Optimization to improve performance on Windows on Arm. This same technique can be applied to your own performance-critical code to achieve similar improvements.
83+
You've applied PGO to reduce execution time by 64% on a division-heavy benchmark. You completed the full PGO workflow: instrument, profile, and optimize. Apply this same technique to performance-critical sections of your own code to achieve similar gains on Windows on Arm.

0 commit comments

Comments
 (0)