Project 5: Image Processing Cache Benchmark
A program that applies a simple filter (like a grayscale conversion or a box blur) to an image represented as a 2D array of pixels. You will compare the performance of two data layouts: an “Array of Structs” (AoS) and a “Struct of Arrays” (SoA).
Quick Reference
| Attribute | Value |
|---|---|
| Primary Language | C |
| Alternative Languages | C++, Rust |
| Difficulty | Level 2: Intermediate |
| Time Estimate | 1-2 weeks |
| Knowledge Area | CPU Caches / Image Processing / Data Representation |
| Tooling | A simple image library (like stb_image.h) or just a raw 2D array. |
| Prerequisites | Project 1 (Locality Benchmarker), comfort with pointers and dynamic allocation. |
What You Will Build
A program that applies a simple filter (like a grayscale conversion or a box blur) to an image represented as a 2D array of pixels. You will compare the performance of two data layouts: an “Array of Structs” (AoS) and a “Struct of Arrays” (SoA).
Why It Matters
This project builds core skills that appear repeatedly in real-world systems and tooling.
Core Challenges
- Representing pixel data in AoS format → maps to the “intuitive”
struct Pixel { r, g, b, a; }layout - Representing pixel data in SoA format → maps to the less intuitive but more performant
struct Pixels { r[], g[], b[], a[]; }layout - Implementing the same algorithm for both layouts → maps to adapting your code to different data structures
- Benchmarking the two approaches → maps to measuring the performance impact of data layout
Key Concepts
- Array of Structs vs. Struct of Arrays (AoS vs. SoA): Mike Acton’s CppCon 2014 talk “Data-Oriented Design and C++”
- Cache Pollution: When your cache is filled with data you don’t need for the current operation.
- Data-Oriented Design: A programming paradigm focused on data layouts for performance.
Real-World Outcome
$ ./image_benchmark image.png
Processing 1920x1080 image...
Benchmarking Grayscale Conversion:
Array of Structs (AoS) layout: 0.045 seconds
Struct of Arrays (SoA) layout: 0.015 seconds
Performance Ratio (SoA is faster by): 3.00x
Benchmarking Full Image Copy (reads all fields):
Array of Structs (AoS) layout: 0.020 seconds
Struct of Arrays (SoA) layout: 0.060 seconds
Performance Ratio (AoS is faster by): 3.00x
Implementation Guide
- Reproduce the simplest happy-path scenario.
- Build the smallest working version of the core feature.
- Add input validation and error handling.
- Add instrumentation/logging to confirm behavior.
- Refactor into clean modules with tests.
Milestones
- Milestone 1: Minimal working program that runs end-to-end.
- Milestone 2: Correct outputs for typical inputs.
- Milestone 3: Robust handling of edge cases.
- Milestone 4: Clean structure and documented usage.
Validation Checklist
- Output matches the real-world outcome example
- Handles invalid inputs safely
- Provides clear errors and exit codes
- Repeatable results across runs
References
- Main guide:
LEARN_C_PERFORMANCE_DEEP_DIVE.md - “Write Great Code, Volume 2: Thinking Low-Level, Writing High-Level” by Randall Hyde