Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Compiler Flags, Layout, and the Machine

โญโญโญ advancedโณ 10 min read๐Ÿ“ Lesson 173 of 204

What -O2 actually assumes, why layout beats micro-opts, and how the same source gets faster by data arrangement.

What the optimizer may and may not do

At -O2 the compiler assumes no undefined behavior: signed overflow won't happen, pointers won't alias char buffers illegally, in-bounds access is guaranteed. UB lets it delete your "safety" checks โ€” which is why UB hunting (module 12) is a performance topic too. It may reorder, vectorize, and inline โ€” but it cannot fix O(nยฒ).

Flags that matter, briefly

-O2 default shipping; -O3 marginal, sometimes worse; -march=native for your machine only; -fsanitize=โ€ฆ never in production; LTO links the optimizer across translation units (module 15 territory).

Layout micro-wins that are actually macro

  • SoA over AoS when loops touch field subsets (module 10).
  • std::vector over std::list almost always โ€” contiguous beats node-based even with extra copying.
  • Smaller structs โ†’ more records per cache line โ†’ fewer misses.
  • Sorting before scanning improves branch prediction and lets early-exit algorithms fire.

None of these require cleverness โ€” only measuring and choosing.