Home Knowledge Base GPU Memory Hierarchy Optimization

GPU Memory Hierarchy Optimization is the systematic tuning of data placement and access patterns across GPU's multi-level memory system to maximize bandwidth utilization and minimize latency — where understanding the hierarchy from registers (20,000 GB/s effective bandwidth) through shared memory (19 TB/s on H100), L1/L2 caches (10-15 TB/s), to global HBM memory (1.5-3 TB/s) enables 5-20× performance improvements through techniques like shared memory tiling that reduces global memory accesses by 80-95%, register blocking that keeps frequently accessed data in fastest storage, and memory coalescing that achieves 80-100% of theoretical bandwidth, making memory hierarchy optimization the most impactful optimization for memory-bound kernels that dominate GPU workloads where 60-80% of kernels are memory-limited rather than compute-limited.

Memory Hierarchy Levels:

<svg viewBox="0 0 760 470" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,Segoe UI,Roboto,sans-serif">
  <rect x="0" y="0" width="760" height="470" fill="#0d1117"/>
  <text x="380" y="28" fill="#e6edf3" font-size="21" font-weight="700" text-anchor="middle">GPU Memory Hierarchy — CUDA Optimization</text>
  <text x="380" y="48" fill="#8b98a5" font-size="12" text-anchor="middle">registers → shared memory → L1/L2 → HBM — each level trades capacity for speed</text>

  <!-- Memory hierarchy pyramid -->
  <rect x="30" y="65" width="350" height="340" rx="6" fill="#080d14" stroke="#233043" stroke-width="1"/>
  <text x="205" y="84" fill="#e6edf3" font-size="10" font-weight="600" text-anchor="middle">Memory Hierarchy (H100)</text>

  <!-- Registers (fastest, smallest) -->
  <rect x="145" y="98" width="120" height="34" rx="4" fill="#14261f" stroke="#34d399" stroke-width="1.2"/>
  <text x="205" y="114" fill="#6ee7b7" font-size="9" font-weight="600" text-anchor="middle">Registers</text>
  <text x="205" y="127" fill="#6b7684" font-size="7" text-anchor="middle">255 per thread · 0 cycles</text>

  <!-- Shared memory -->
  <rect x="115" y="142" width="180" height="34" rx="4" fill="#0b1220" stroke="#60a5fa" stroke-width="1.2"/>
  <text x="205" y="158" fill="#93c5fd" font-size="9" font-weight="600" text-anchor="middle">Shared Memory (SMEM)</text>
  <text x="205" y="171" fill="#6b7684" font-size="7" text-anchor="middle">228 KB/SM · ~20 cycles · 19 TB/s</text>

  <!-- L1 cache -->
  <rect x="95" y="186" width="220" height="34" rx="4" fill="#0b1220" stroke="#a78bfa" stroke-width="1"/>
  <text x="205" y="202" fill="#c4b5fd" font-size="9" font-weight="600" text-anchor="middle">L1 Cache</text>
  <text x="205" y="215" fill="#6b7684" font-size="7" text-anchor="middle">256 KB/SM · ~30 cycles · shared with SMEM</text>

  <!-- L2 cache -->
  <rect x="75" y="230" width="260" height="34" rx="4" fill="#0b1220" stroke="#f59e0b" stroke-width="1"/>
  <text x="205" y="246" fill="#fbbf24" font-size="9" font-weight="600" text-anchor="middle">L2 Cache</text>
  <text x="205" y="259" fill="#6b7684" font-size="7" text-anchor="middle">50 MB · ~200 cycles · 12 TB/s</text>

  <!-- HBM (global memory) -->
  <rect x="55" y="274" width="300" height="40" rx="4" fill="#0b1220" stroke="#f87171" stroke-width="1.2"/>
  <text x="205" y="292" fill="#fca5a5" font-size="9" font-weight="600" text-anchor="middle">HBM3e (Global Memory)</text>
  <text x="205" y="306" fill="#6b7684" font-size="7" text-anchor="middle">80 GB · ~400 cycles · 3.35 TB/s</text>

  <!-- Host/PCIe -->
  <rect x="55" y="324" width="300" height="30" rx="4" fill="#1a0a0a" stroke="#475569" stroke-width="0.8"/>
  <text x="205" y="343" fill="#6b7684" font-size="8" text-anchor="middle">CPU Host (PCIe 5.0: 64 GB/s · NVLink: 900 GB/s)</text>

  <!-- Speed/capacity arrows -->
  <text x="50" y="190" fill="#34d399" font-size="7" text-anchor="middle">faster</text>
  <text x="50" y="205" fill="#34d399" font-size="9" text-anchor="middle">↑</text>
  <text x="50" y="265" fill="#f87171" font-size="9" text-anchor="middle">↓</text>
  <text x="50" y="280" fill="#f87171" font-size="7" text-anchor="middle">bigger</text>

  <text x="205" y="375" fill="#8b98a5" font-size="8" text-anchor="middle">key insight: keep data in SMEM/registers</text>
  <text x="205" y="390" fill="#8b98a5" font-size="8" text-anchor="middle">to avoid slow HBM round-trips</text>

  <!-- Right: Optimization techniques -->
  <rect x="400" y="65" width="330" height="340" rx="6" fill="#080d14" stroke="#233043" stroke-width="1"/>
  <text x="565" y="84" fill="#e6edf3" font-size="10" font-weight="600" text-anchor="middle">Optimization Strategies</text>

  <text x="420" y="110" fill="#34d399" font-size="9" font-weight="600">1. Maximize shared memory reuse</text>
  <text x="420" y="126" fill="#8b98a5" font-size="8">tile GEMM into SMEM blocks (128×128 tiles)</text>
  <text x="420" y="140" fill="#6b7684" font-size="7.5">FlashAttention: fuse Q×K×V in SRAM, never write attn matrix to HBM</text>

  <text x="420" y="164" fill="#60a5fa" font-size="9" font-weight="600">2. Coalesced global memory access</text>
  <text x="420" y="180" fill="#8b98a5" font-size="8">adjacent threads access adjacent addresses</text>
  <text x="420" y="194" fill="#6b7684" font-size="7.5">128-byte transaction: 32 threads × 4 bytes = 1 cache line</text>

  <text x="420" y="218" fill="#a78bfa" font-size="9" font-weight="600">3. Occupancy tuning</text>
  <text x="420" y="234" fill="#8b98a5" font-size="8">balance registers/SMEM per block vs active warps</text>
  <text x="420" y="248" fill="#6b7684" font-size="7.5">more warps = hide latency, fewer = more resources/thread</text>

  <text x="420" y="272" fill="#f59e0b" font-size="9" font-weight="600">4. Async memory copies (cp.async)</text>
  <text x="420" y="288" fill="#8b98a5" font-size="8">overlap HBM→SMEM with compute</text>
  <text x="420" y="302" fill="#6b7684" font-size="7.5">software pipelining: load next tile while computing current</text>

  <text x="420" y="326" fill="#f87171" font-size="9" font-weight="600">5. Avoid bank conflicts</text>
  <text x="420" y="342" fill="#8b98a5" font-size="8">SMEM has 32 banks — pad arrays to avoid collisions</text>
  <text x="420" y="356" fill="#6b7684" font-size="7.5">conflict = serialization = wasted cycles</text>

  <text x="420" y="380" fill="#38bdf8" font-size="9" font-weight="600">6. L2 persistence (H100+)</text>
  <text x="420" y="396" fill="#8b98a5" font-size="8">pin hot data in L2 across kernel launches</text>

  <!-- Footer -->
  <text x="380" y="432" fill="#8b98a5" font-size="8.5" text-anchor="middle">FlashAttention's entire insight: keep everything in SRAM (19 TB/s) instead of HBM (3.35 TB/s) → 5× faster attention</text>
  <text x="380" y="452" fill="#6b7684" font-size="11" text-anchor="middle">GPU programming is memory programming — the fastest kernel is the one that never touches global memory.</text>
</svg>

Shared Memory Optimization:

Register Optimization:

Cache Optimization:

Memory Access Patterns:

Bandwidth Optimization:

Latency Hiding:

Unified Memory:

Memory Bandwidth Bottlenecks:

Advanced Techniques:

Profiling and Tuning:

Common Patterns:

Best Practices:

GPU Memory Hierarchy Optimization is the art of data orchestration across multiple storage levels — by understanding the 1000× performance difference between registers and global memory and applying techniques like shared memory tiling, memory coalescing, and register blocking, developers achieve 5-20× performance improvements and 80-100% of theoretical bandwidth, making memory hierarchy optimization the most critical skill for GPU programming where the vast majority of kernels are memory-bound and proper data placement determines whether applications achieve 5% or 80% of peak performance.

gpu memory hierarchy optimizationcuda memory typesgpu cache optimizationshared memory optimizationgpu memory bandwidth

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.