In short: The roofline model plots a kernel's achievable performance against its arithmetic intensity (FLOPs per byte of DRAM traffic), so you can tell at a glance whether it is starved by memory bandwidth or limited by raw compute — and which optimization will actually move the needle.
Modern AI accelerators advertise staggering peak numbers — an NVIDIA H100 SXM quotes roughly 989 TFLOP/s of dense BF16 tensor throughput. Yet a real transformer layer often reaches a small fraction of that. The reason is almost never the multiplier array; it is that the operands cannot be delivered from memory fast enough. The roofline model, introduced by Williams, Waterman, and Patterson, gives engineers a single, intuitive picture that explains why, and tells them where to spend effort.
Arithmetic intensity: the x-axis that decides everything
Arithmetic intensity (AI, or operational intensity) is the ratio of useful arithmetic operations to bytes moved across the memory boundary you care about — usually DRAM/HBM:
Arithmetic Intensity = FLOPs ÷ Bytes transferred
It is measured in FLOP/byte. A kernel with low intensity re-uses each byte only once or twice; a kernel with high intensity grinds many operations on data already resident in on-chip SRAM or registers. Intensity is a property of the algorithm and its blocking, not of the hardware, which is exactly why it is the knob you control.
Worked number: A fused multiply-add on two FP16 values is 2 FLOPs. If every operand is freshly fetched from HBM (2 bytes each, plus storing the result), intensity is roughly 2 FLOP / 6 bytes ≈ 0.33 — hopelessly memory-bound on any modern GPU.
Reading the roofline
Plot attainable performance (GFLOP/s) against arithmetic intensity on log-log axes. Two ceilings appear. The flat ceiling is peak compute (π), set by the number of FMA units and clock. The sloped ceiling is peak memory bandwidth (β) times intensity — doubling intensity doubles attainable performance until you hit the flat roof. They cross at the ridge point, I* = π / β.
For an H100 with ~989 BF16 TFLOP/s and ~3.35 TB/s of HBM3, the ridge point sits near 295 FLOP/byte. Any kernel below that intensity cannot possibly reach peak compute, no matter how clever the inner loop — the memory system is the wall.
Memory-bound vs compute-bound in real kernels
| Kernel | Approx. intensity | Regime | Best lever |
|---|---|---|---|
| Element-wise add / activation | ~0.25 FLOP/byte | Memory-bound | Fuse into neighbors |
| Vector-matrix (GEMV, batch=1 decode) | ~1–2 | Memory-bound | Batch, quantize weights |
| Large square GEMM (training) | 50–500+ | Compute-bound | Better tiling, tensor cores |
| Attention (long context, unfused) | low | Memory-bound | Fuse (FlashAttention) |
This table captures the single most important intuition in LLM serving: training is usually compute-bound, autoregressive decode is usually memory-bound. Generating one token at batch size 1 multiplies a huge weight matrix by a single activation vector — every weight byte is used once, so intensity is near 1 and you are limited by how fast HBM can stream the weights. This is precisely why INT8/FP8 weight quantization speeds up decode: it halves the bytes, shifting you rightward and upward along the bandwidth roof.
Optimizing kernels with the model
The roofline turns optimization from guesswork into a decision tree:
- Left of the ridge (memory-bound): raise intensity. Fuse operations so intermediates stay in SRAM, tile loops to improve cache re-use, quantize to shrink bytes, and avoid materializing large temporaries. FlashAttention is the textbook win — it keeps the N×N attention scores in on-chip memory instead of writing them to HBM, lifting intensity by an order of magnitude.
- Right of the ridge (compute-bound): you are already bandwidth-efficient; now chase the flat roof. Use tensor cores (map the math to the MMA instruction shapes), improve occupancy, exploit structured sparsity, or drop precision to a faster datatype.
- Below both roofs: you are leaving performance on the table from poor overlap, low occupancy, or bank conflicts — profile before rewriting.
Practical tip: Vendor profilers build the roofline for you. NVIDIA Nsight Compute emits a hardware roofline per kernel; Intel Advisor pioneered the automated Cache-Aware Roofline. Hierarchical rooflines add separate roofs for L2 and shared memory, exposing which level of the memory hierarchy is the real bottleneck.
Why hardware designers care too
The roofline is not only a software tool. When architects at companies that build accelerators — and the EDA teams at Avecas VLSI design services who help realize such silicon — choose an HBM stack width or size an on-chip SRAM buffer, they are implicitly setting β and the ridge point. A chip meant for inference with low-intensity decode workloads benefits far more from extra bandwidth and bigger caches than from more raw TFLOPs. The model makes that trade explicit and quantifiable.
Limitations to keep honest
The classic roofline assumes perfect overlap of compute and memory, counts only DRAM traffic, and ignores latency, instruction mix, and startup effects. Real kernels can sit below the roof for reasons the single plot does not show. Treat it as a first-order diagnostic that tells you which wall you are hitting, then profile for the second-order detail. Pair it with reading on hardware for deep learning and HBM memory bandwidth to connect the model to the silicon it describes.
Want to profile and optimize real GPU kernels, build rooflines in Nsight, and reason about AI accelerators like an engineer? Our CourseTron AI Hardware track walks through it hands-on — and for structured VLSI and training cohorts, see ChipXpert training programs.
FAQ
What is a good arithmetic intensity to aim for?
Aim to land at or past the hardware's ridge point — around 295 FLOP/byte for an H100's HBM3 roof. Below it you are bandwidth-limited; matching or exceeding it means compute is the only remaining ceiling.
Why is LLM text generation memory-bound?
Autoregressive decode processes one token at a time, so the large weight matrices are multiplied by a single activation vector. Each weight byte is used essentially once, giving intensity near 1 — the GPU spends its time waiting on HBM, not computing.
Does quantization change where I sit on the roofline?
Yes. Moving weights from FP16 to INT8/FP8 halves or quarters the bytes transferred without changing the FLOP count, raising arithmetic intensity and shifting a memory-bound kernel up and to the right toward higher attainable throughput.
Which tools draw the roofline automatically?
NVIDIA Nsight Compute produces a per-kernel hardware roofline, and Intel Advisor offers the Cache-Aware Roofline with hierarchical roofs for each memory level, so you rarely need to plot it by hand.