Inferensys

Glossary

Loop Tiling

Loop tiling, also known as loop blocking, is a compiler optimization that partitions loop iterations into smaller blocks to improve data locality and cache utilization, essential for high-performance AI/ML workloads.
Data scientist building training data pipeline on laptop, data preprocessing visible, technical workspace.
COMPUTE GRAPH OPTIMIZATION

What is Loop Tiling?

Loop tiling, also known as loop blocking, is a critical compiler optimization for memory-bound operations in machine learning and high-performance computing.

Loop tiling is a loop nest transformation that partitions loop iteration spaces into smaller blocks or tiles to improve data locality and cache utilization. By reordering computations to work on subsets of data that fit within a processor's cache hierarchy, it dramatically reduces expensive accesses to main memory. This optimization is foundational for performance in matrix multiplication, convolution, and other stencil computations central to neural network inference.

The transformation involves splitting original loops into outer loops that stride across tiles and inner loops that iterate within a tile. The optimal tile size is determined by hardware characteristics like cache capacity and memory bandwidth, often using a cost model or auto-tuning. It is a core technique within the polyhedral model for loop optimization and works synergistically with vectorization and parallelization to maximize hardware efficiency on CPUs, GPUs, and NPUs.

COMPUTE GRAPH OPTIMIZATION

Key Characteristics of Loop Tiling

Loop tiling is a fundamental compiler optimization that restructures nested loops to maximize data reuse from fast cache memory, directly addressing the memory wall problem in compute-intensive kernels.

01

Core Mechanism: Blocking for Locality

Loop tiling, also called loop blocking, partitions the iteration space of a loop nest into smaller blocks or tiles. The primary goal is to ensure that all data within a tile fits into a processor's cache hierarchy (L1, L2). This transforms a computation with poor temporal locality into one with high locality, drastically reducing costly accesses to main memory (DRAM).

  • Key Transformation: It changes the loop order from, for example, (i, j) to (ti, tj, ii, jj), where ti/tj iterate over tiles and ii/jj iterate within a tile.
  • Target: Memory-bound operations like dense matrix multiplication, convolutions, and stencil computations.
02

Tile Size Selection: A Critical Trade-Off

Choosing the optimal tile size is non-trivial and balances multiple constraints. The ideal tile maximizes data reuse without exceeding cache capacity or introducing excessive overhead.

  • Cache Capacity Bound: The working set of a tile (input + output data) must fit within the target cache (e.g., L1).
  • Translation Lookaside Buffer (TLB) Coverage: Tile dimensions should be chosen to minimize TLB misses for virtual-to-physical address translation.
  • Hardware-Specific Tuning: Optimal sizes depend on the specific cache line size, associativity, and bandwidth of the target CPU or accelerator. This often requires auto-tuning or analytical modeling.
03

Interaction with Other Optimizations

Loop tiling is rarely applied in isolation; it enables and synergizes with other critical compiler passes.

  • Enables Vectorization: By creating contiguous, predictable inner-loop access patterns within a tile, tiling provides ideal conditions for SIMD vectorization.
  • Facilitates Parallelization: Tiling creates independent units of work (tiles) that can be distributed across multiple CPU cores or GPU threads for parallel execution.
  • Foundation for the Polyhedral Model: Tiling is a canonical transformation within the polyhedral model, a mathematical framework for loop nest optimization that ensures correctness across complex transformations like fusion and skewing.
04

Hardware-Aware Implementation

Effective tiling must account for the memory hierarchy and compute architecture of the target hardware.

  • Multi-Level Tiling: For deep cache hierarchies, nested tiling is used—a small tile for L1 cache, a larger tile for L2/L3 cache. This is essential for operations like general matrix multiply (GEMM).
  • Register Tiling: The innermost loop levels can be tiled to hold operands directly in CPU registers, minimizing even L1 cache accesses.
  • Accelerator-Specific Tiling: On GPUs and NPUs, tiling dimensions are chosen to optimize for shared memory/SRAM capacity and thread block/wavefront execution models.
05

Performance Modeling: The Roofline

The effectiveness of loop tiling is perfectly illustrated by the Roofline performance model. This model plots attainable performance (FLOPS/sec) against operational intensity (FLOPS/byte).

  • Memory-Bound Region: Kernels with low operational intensity are limited by memory bandwidth. Tiling increases operational intensity by reusing cached data, moving the kernel's point to the right on the Roofline chart.
  • Compute-Bound Region: Once operational intensity is high enough, performance hits the processor's peak compute ceiling. Tiling ensures the kernel can saturate this compute capacity by keeping the functional units fed with data.
06

Practical Example: Tiled Matrix Multiplication

Consider naive matrix multiplication C[i][j] += A[i][k] * B[k][j]. The inner loop has poor cache locality as it strides through entire rows/columns.

A tiled version introduces block indices (ib, jb, kb) and inner indices (ii, jj, kk):

code
for ib in range(0, N, TILE):
  for jb in range(0, N, TILE):
    for kb in range(0, N, TILE):
      # Compute on tile C[ib:ib+TILE][jb:jb+TILE]
      # using A[ib:ib+TILE][kb:kb+TILE] and B[kb:kb+TILE][jb:jb+TILE]
  • Result: The sub-matrices A_tile and B_tile are loaded into cache once and reused extensively for all computations within the (ib, jb) tile, reducing memory accesses from O(N³) to roughly O(N³/√TILE).
COMPUTE GRAPH OPTIMIZATION

Loop Tiling vs. Other Loop Optimizations

A comparison of loop tiling against other fundamental loop nest transformations used by compilers and inference frameworks to optimize computational graphs for memory hierarchy and parallelism.

OptimizationPrimary GoalEffect on Control FlowKey ApplicabilityInteraction with Hardware

Loop Tiling (Blocking)

Improve data locality & cache reuse

Partitions iteration space into blocks

Memory-bound nested loops (e.g., matmul, conv)

Exploits cache hierarchy; critical for CPUs/GPUs

Loop Unrolling

Reduce loop overhead & enable ILP

Duplicates loop body; reduces iteration count

Loops with small, fixed trip counts

Exposes more operations for scalar/SIMD optimization

Loop Fusion

Reduce intermediate memory traffic

Combines adjacent loops into one

Loops with same iteration space & no dependency

Reduces kernel launch overhead & total loads/stores

Loop Fission (Distribution)

Increase parallelism or fit in cache

Splits a single loop into multiple loops

Large loop bodies with independent statements

Enables parallel execution of new loops

Loop Interchange

Improve stride-1 memory access

Changes nesting order of loops

Nested loops accessing multi-dimensional arrays

Aligns access pattern with memory layout (e.g., row-major)

Loop Skewing

Enable parallelization or tiling

Transforms iteration space to alter dependencies

Loops with carried dependencies (e.g., wavefront)

Exposes new parallelism for vector/tile scheduling

Vectorization

Exploit data-level parallelism (SIMD)

Replaces scalar ops with vector instructions

Innermost loops with independent iterations

Requires SIMD units (CPU/GPU vector lanes)

Loop Peeling

Handle edge cases or align accesses

Removes initial/final iterations from main loop

Loops with prologue/epilogue for alignment

Facilitates subsequent vectorization or unrolling

COMPUTE GRAPH OPTIMIZATION

Primary Use Cases for Loop Tiling

Loop tiling is a foundational compiler optimization that restructures nested loops to exploit data locality. Its primary applications are in performance-critical domains where memory access patterns dominate execution time.

LOOP TILING

Frequently Asked Questions

Loop tiling, also known as loop blocking, is a critical compiler optimization for improving data locality in memory-bound computations. These questions address its core mechanisms, applications, and relationship to other graph optimizations.

Loop tiling (or loop blocking) is a loop nest transformation that partitions loop iteration spaces into smaller blocks or tiles to improve data locality and cache utilization. It works by restructuring nested loops to process data in chunks that fit within the processor's cache hierarchy. Instead of streaming entire rows or columns of a large matrix through cache, which leads to frequent cache misses, tiling ensures that data within a tile is reused multiple times while it remains in the faster L1 or L2 cache. This transformation is fundamental for optimizing performance-critical operations like matrix multiplication (GEMM) and convolution on CPU and GPU architectures.

Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.