Performance in C++: measuring and speeding up
You find bottlenecks with sound measurement and profiling and speed C++ code up, with evidence, through data layout, allocation and compiler optimisation.
Level 501 · 16 lessons · 15 practice labs
Lessons
Measuring
- Measuring correctly: Google Benchmark and noise
- Profiling with perf
- Seeing hot spots with flame graphs
- Short task: find the hot spot of a slow tool
Memory and caches
- Cache locality: data layout matters
- Array of structs versus struct of arrays
- The cost of allocation and reserve
- Custom memory resources with pmr
- Small string and small object optimisation
- Short task: speed up by changing the data layout
The compiler and the CPU
- Inlining, LTO and PGO
- Branch prediction and branchless code
- Vectorisation and SIMD
- Compile time and binary size
- Short task: make a loop vectorisable
Capstone
- Capstone: make a log indexer five times faster, with measurements
Practice labs
- Guarding benchmarked code from elimination: Fix a benchmark showing zero time because the compiler removed the code with DoNotOptimize and compare two functions fairly.
- Finding the hot function with perf: Take a perf recording of a slow text matcher, find the function spending most of the time and document the finding with the report output.
- Finding and removing a bottleneck from a flame graph: Generate a flame graph of Karaçam Mobilya's order merge tool, remove the needless work in the widest frame and show at least a threefold speed-up by measurement.
- Traversing a matrix in cache-friendly order: Change a summing loop that walks column by column to row order and report the difference by timing both versions.
- Turning an array of structs into a struct of arrays: Change the data layout to a struct of arrays for a hot loop that reads only two fields, keeping results identical and measuring the speed-up.
- Moving a pointer-chasing structure to a flat index: Move a lookup structure that keeps scattered linked-list nodes to a sorted flat vector, count cache misses and meet the fivefold speed target.
- Avoiding reallocations with reserve: Bring the number of reallocations to zero with reserve for a vector whose size is known in advance and pass the allocation-counter test.
- Benefiting from the small string optimisation: Change code that allocates on every lookup because of long-prefixed keys to short keys and string_view lookup and measure the allocation count.
- Moving per-request allocations to a pmr arena: Move a parser that makes thousands of small allocations per request to pmr containers on a monotonic_buffer_resource and meet the allocation and time targets.
- Comparing optimisation levels: Write a script that builds the same program at different optimisation levels and produces a table of time and binary size.
- Enabling inlining across translation units: Remove the call cost of a small function in another source file within a hot loop through link-time optimisation and verify from the compiler output.
- Setting up a profile-guided build pipeline: Write a script that collects a profile with a representative workload and uses it in a second build, measure the gain and report the build-time and size cost.
- Measuring the effect of branch prediction: Measure the same conditional sum on sorted and shuffled data and write the program that produces a short report explaining the difference.
- Writing a conditional count without branches: Convert a threshold-counting loop slowed by unpredictable branches to branchless arithmetic and show with random tests the results are identical.
- Making a loop vectorisable: Find from the compiler's vectorisation report the aliasing and dependency reasons blocking a loop, remove them and verify vectorisation from the output.
About this course
You find bottlenecks with sound measurement and profiling and speed C++ code up, with evidence, through data layout, allocation and compiler optimisation.
What you will learn
- Measuring
- Memory and caches
- The compiler and the CPU
- Capstone
Prerequisites
You should be experienced in the topics of the same path up to level 401.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 501; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.