GPU Memory Pool Allocators are the caching memory management systems that maintain pre-allocated pools of GPU memory to eliminate the overhead of frequent cudaMalloc/cudaFree calls — reducing allocation latency from milliseconds to microseconds, preventing memory fragmentation, and enabling the rapid tensor allocation/deallocation patterns required by deep learning frameworks.
The Problem with Raw CUDA Allocation
cudaMalloc(): ~1-10 ms per call — extremely slow (requires GPU driver interaction, page table updates).- Deep learning: Each training iteration allocates/frees hundreds of tensors.
- Without pooling: 200 allocations × 5 ms = 1 second of pure allocation overhead per iteration.
- With pooling: 200 allocations × 5 μs = 1 ms — 1000x faster.
How Caching Allocators Work
1. First allocation: Pool calls cudaMalloc for a large block (e.g., 2GB). 2. User requests 256MB: Pool carves out 256MB from the large block — returns pointer. 3. User frees 256MB: Pool marks the segment as available — does NOT call cudaFree. 4. Next 256MB request: Pool reuses the freed segment — zero allocation overhead. 5. Pool grows: If existing blocks are insufficient, allocate another large block.
PyTorch CUDA Caching Allocator
- Default allocator for all PyTorch GPU tensors.
- Maintains separate pools for small (< 1MB) and large (≥ 1MB) allocations.
- Uses best-fit strategy with block splitting to minimize fragmentation.
torch.cuda.memory_summary(): Shows allocated, reserved, and fragmented memory.torch.cuda.empty_cache(): Returns unused cached blocks to CUDA (but doesn't help with fragmentation).
Memory Fragmentation
- Even with pooling, fragmentation occurs: Many small free blocks but no contiguous space for a large allocation.
- Example: 8GB reserved, 2GB in use, but largest free block is only 500MB → cannot allocate 1GB tensor.
- Mitigation: PyTorch 2.x uses
expandable_segmentsconfiguration to reduce OS-level fragmentation.
CUDA Memory Pool API (CUDA 11.2+)
cudaMemPool_t: Native CUDA memory pool support.cudaMallocAsync()/cudaFreeAsync(): Stream-ordered allocation — allocation tied to CUDA stream.- Benefit: GPU hardware manages allocation ordering — further reduces synchronization overhead.
Memory Management Best Practices
- Pre-allocate: Allocate maximum-size tensors once at startup, reuse buffers.
- Gradient accumulation: Process smaller micro-batches to reduce peak memory.
- Mixed precision: FP16/BF16 tensors use half the memory of FP32.
- Activation checkpointing: Trade compute for memory by recomputing activations during backward.
GPU memory pool allocators are essential infrastructure for all GPU computing frameworks — without them, the rapid tensor allocation patterns of modern deep learning and scientific computing would be throttled by driver-level allocation overhead, making interactive and training workloads impractically slow.
Related Topics
Explore 500+ Semiconductor & AI Topics
From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.