athola/loop-optimization
Decides hand-vs-compiler for loop transforms (unrolling, SIMD, fusion, hoisting). Use when reviewing/authoring a hot loop or tempted to hand-optimize one.
npx skills add https://github.com/athola/claude-night-market --skill loop-optimization
A decision rule for the five common loop transformations. Its value
is knowing when manual application is redundant (the compiler already
does it) or harmful (it defeats the vectorizer or fools your
benchmark).
body, shift-instead-of-multiply, bespoke SIMD).
optimize it by hand.
Skill(pensive:architecture-review).
Skill(pensive:performance-review).
profiler.
loop-invariant code motion and strength reduction: both run
automatically at -O2/-O3, so the manual form is redundant. Leave
unrolling to the compiler as well. Unlike the other two it is not on
by default (GCC needs -funroll-loops), but the compiler owns the
profitability decision and manual unrolling routinely defeats the
auto-vectorizer.
restrict /__restrict__) and loop shape first. Confirm with an optimization
report (-fopt-info-vec-missed, -Rpass-missed=loop-vectorize).
Reach for intrinsics last and accept the portability cost.
compiler misses, loop fusion (guard against register and cache
pressure), and multi-accumulator unrolling to break a floating-point
reduction chain the compiler legally will not reorder.
vectorize via NumPy, fuse passes via numexpr/Numba. Do not hand-unroll
or hand-strength-reduce: the cost is bytecode dispatch, not loop
control.
| Technique | Helps where | When NOT to apply by hand |
|-----------|-------------|---------------------------|
| Unrolling | C/C++/Rust FP reduction chains (multi-accumulator) | Auto-vectorizable loops (defeats vectorizer); OOO CPUs; icache pressure; Python |
| SIMD / vectorization | C/C++/Rust loops the compiler misses; Python via NumPy | Before fixing aliasing/loop shape; short trip counts; unverified that emitted SIMD runs |
| Loop fusion | Bandwidth-bound array loops; Python via numexpr/Numba | When it spills registers or mixes strided access; compute-bound bodies; blocks vectorization |
| Hoisting (LICM) | Python (no compiler does it); C/C++/Rust only when aliasing blocks the proof | -O2+ compiled code: redundant and can lengthen live ranges |
| Strength reduction | Compilers do it; near-useless by hand | -O2+ compiled code: blocks the compiler's IV analysis and vectorization |
or synthetic input can invert to slower on production data, because
synthetic input hides effects such as branch misprediction on real
value distributions. Benchmark on production-distribution data with
optimizer barriers, or do not claim the win.
compiler emitted SIMD" does not mean "SIMD ran." Confirm with codegen
or optimization reports, not source inspection.
Both traps tie into Skill(imbue:proof-of-work): a speedup claim needs
evidence on representative data, not assertion.
recommendation is "do not optimize."
left to the compiler unless an optimization report shows the
compiler failed (aliasing) and the manual form was verified faster.
check that the vectorized path actually executes.
data, not synthetic or reused input.
Take athola/loop-optimization from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.