Projects — Phase 4¶
Two projects. Both concrete. The first is the template you’ll fork for the rest of the roadmap; the second proves the template works on real code. Every remaining project in Phase 5 will be built on top of P4.1. Every hiring manager who clicks your GitHub will land on this repo first. Treat it accordingly.
P4.1 — Reference C++20 Project Template (W23)¶
Goal: produce a public GitHub template repository (raghul-cpp-template or your naming) that a stranger can git clone and have a green build, passing tests, and running benchmarks inside five minutes.
Layout¶
raghul-cpp-template/
├── .clang-format
├── .clang-tidy
├── .github/workflows/ci.yml
├── .gitignore
├── CMakeLists.txt
├── CMakePresets.json
├── Dockerfile
├── LICENSE # MIT or Apache-2.0
├── README.md # onboarding + status badges
├── cmake/
│ ├── Sanitizers.cmake
│ └── mynnConfig.cmake.in
├── conanfile.txt # branch: conan-flavor
├── vcpkg.json # branch: main
├── include/mynn/
│ ├── layer.hpp
│ └── version.hpp
├── src/
│ ├── layer.cpp
│ └── version.cpp
├── apps/
│ └── hello.cpp # one demo binary
├── tests/
│ ├── CMakeLists.txt
│ ├── test_layer.cpp # gtest
│ └── test_layer_catch.cpp # catch2 (one example, so you know both)
├── benchmarks/
│ ├── CMakeLists.txt
│ └── bench_layer.cpp
└── docs/
└── ARCHITECTURE.md
Acceptance criteria¶
Public GitHub repo, marked “Template repository” in settings.
README has status badges: CI, license, C++ standard (C++20).
cmake --preset debug && cmake --build --preset debug && ctest --preset debugworks out of the box on Ubuntu 24.04 and macOS 14.cmake --preset asanruns the test suite under ASan + UBSan. Any deliberate bug is caught.cmake --preset tsanruns any threaded test under TSan.Two branches:
main(vcpkg-based) andconan-flavor(Conan 2). Both green in CI.CI matrix:
{ubuntu-24.04, macos-14} × {clang-18, gcc-13 on Linux only} × {debug, release, asan}— all cells green.fail-fast: false.Dockerfilebuilds locally; a fresh container passes the full test suite..clang-formatand.clang-tidypresent and enforced in alintCI job.At least one Google Benchmark that uses
benchmark::DoNotOptimize.--benchmark_format=jsonoutput archived as a CI artifact.README onboarding section: git clone → running tests in ≤ 5 minutes. Time a friend if possible.
Zero warnings on default preset with
-Wall -Wextra -Wpedantic.
Traps to avoid¶
Don’t over-scope. The library
mynn::layerhere is a two-function stub — the point is the scaffolding, not the code.Don’t check in
build/,vcpkg_installed/, or.conan2/.Don’t ship a template with
TODOin the README onboarding section. Fix it before pushing.Don’t ship one CI job that says “passed” but silently skipped tests. Verify at least one test ran per matrix cell.
Employer signal¶
Anyone senior reviewing your GitHub will click this repo first. What they see in 30 seconds:
Modern target-based CMake (skim
CMakeLists.txt).Presets = one-command builds (skim
CMakePresets.json).Real CI matrix (skim
.github/workflows/ci.ymlfor the strategy block).Sanitizers wired (skim
cmake/Sanitizers.cmake).Package manager integration (glance at
vcpkg.jsonorconanfile.txt).Tests + benchmarks separately (skim directories).
If all six read as “knows what they’re doing”, the rest of your GitHub gets a favorable read. If any of them read as “copy-pasted from a 2015 tutorial”, the rest gets a skeptical read. This is the halo effect. Own it.
Publish¶
Public GitHub, MIT or Apache-2.0.
Link on LinkedIn (“my C++ project template”).
Blog post walking through why each file exists. Post to Reddit r/cpp, Hacker News. Feedback improves the template.
Time budget¶
5–8 focused hours across W23. If you spend 20 hours on aesthetics, you’re avoiding the harder parts of Phase 4. Move on.
P4.2 — Refactor Phase 3 Thread Pool onto the Template (W26)¶
Goal: take your P3.2 thread pool (from Phase 3) — which was probably a single-directory main.cpp + one class — and rebuild it as a proper library on top of the P4.1 template. Prove the template works for something real.
What you’re adding to the thread pool¶
gtest suite with:
Basic tests: submit/get, exceptions propagated via
std::future, shutdown semantics.Stress test: submit 10,000 tasks that increment an
std::atomic<int>, verify final count.TSan test: deliberately race a naked
int(in a separateTEST_DISABLED_BY_DEFAULT) so you have a positive control that TSan catches races in this codebase.Death test: submitting to an already-shutdown pool aborts with a clear message.
Google Benchmark suite:
Throughput at pool sizes 1, 2, 4, 8, 16 workers.
Tail latency: task submit-to-complete p50/p99 (log per-task, sort, report).
Compare against
std::async(std::launch::async, ...)as a baseline. Your pool should win at high task counts (less thread-creation overhead).
Sanitizer coverage in CI:
Full test suite under ASan + UBSan (unit + non-stress subset of stress).
Full test suite under TSan.
Both green in CI.
API cleanup:
Public header in
include/mypool/,PUBLICinclude dir, exported asmypool::mypool.find_package(mypool)works from a consumer project.
Acceptance criteria¶
Repo initialized from your P4.1 template (use GitHub’s “Use this template” button).
include/mypool/pool.hppwith clean interface; implementation insrc/pool.cpp.≥ 15 gtest tests. At least one fixture, one parameterized, one death test.
Google Benchmark reports throughput and p99 latency. Numbers checked in as
benchmarks/results/<date>-<machine>.md.CI matrix green on both branches (Debug, Release, ASan, TSan).
TSan positive control: with
TEST_DISABLED_BY_DEFAULT_RaceCatchenabled, TSan reports a race. Enable the test in atsan-onlyCI cell.README: install (
vcpkg install mypool— aspirational — orFetchContent), API example, benchmark chart.A
consumer/subdirectory (or sibling repo) that doesfind_package(mypool)and links, proving the export machinery works.
Traps¶
False positives under TSan from lock-free code. If you use
std::atomiccorrectly, TSan should be silent. If you get a report, understand why before annotating it away.Benchmark contamination: two benchmark runs on the same machine can differ 10% because of the browser you opened. Report median-of-5 or use
--benchmark_min_time.Header-only temptation: don’t turn the pool into an
INTERFACElibrary. You want to prove out static-library export.Testing the wrong thing: don’t just test the queue implementation. Test the thread pool: correct results under contention, no deadlock on destruction, proper exception propagation.
Employer signal¶
“Show me a project where you’ve done concurrency in C++” — this is that answer. The bar isn’t the thread pool itself (study partners have seen 500 of them). The bar is: has it been shipped with the right infrastructure? Sanitizers, benchmarks, CI, published API. Owning that infrastructure is a real signal; the thread pool is the artifact the signal happens to sit on.
Publish¶
Public repo linked from your resume as “C++ concurrency work”.
A short blog post: benchmarks vs
std::async, tail latency graph, one bug you found with TSan while writing it.
Time budget¶
8–12 focused hours across W26. Don’t rewrite the pool from scratch — you already have it. This is a repackaging exercise, plus adding real tests and benchmarks.
What both projects together buy you¶
Your GitHub reads professional in 30 seconds. Two flagship repos at the top of your profile that a hiring manager can navigate.
You are now unblocked for Phase 5. Every Phase 5 project (
mynnfrom Eigen,mynn-pyvia pybind11,mynn-servevia ONNX Runtime,arrow-pipe) forks from P4.1. You spend zero energy on infrastructure in Phase 5 — all of it goes to the ML content.You have muscle memory for modern CMake, sanitizers, GHA matrices, and package managers. In an study or on the job, you don’t Google — you type.
Do not skip these. Every hour spent here saves five later.
Nav: ← 05 CI and Docker · Phase 4 README · Phase 5 →