← Fri, Sep 18 digest

Size-Specialized Memory Allocation

read article ↗ hn thread ↗

summary

Go 1.27 introduces size-specialized memory allocation for objects 80 bytes or smaller to improve performance. By creating specialized functions for specific span classes, the runtime reduces overhead and allows the compiler to perform better optimizations. This approach results in allocations being up to 30% faster, which can increase overall program speed by up to 1%.

key points

  1. The runtime now uses specialized mallocgc functions for various span classes, allowing the compiler to replace generic memory clearing calls with direct, optimized instructions. This eliminates function call overhead and branches for the most common small allocations.
  2. To prevent instruction cache pollution and executable size growth, the team limited specialization to allocations under 80 bytes. This ensures that the specialized code remains in the cache and does not crowd out user code, maintaining a balance between performance gains and cache efficiency.
  3. The specialized functions are generated using an AST-based inliner to ensure consistency and avoid manual maintenance errors. This allows the common logic to be written in standard Go code while producing highly optimized, specialized variants for each span class.

who should read it

Go developers and runtime engineers who want to understand how the internal memory management of the Go language improves performance without requiring code changes from the user.

discussion positive

consensus

Commenters agree that while size-specialized allocation can provide performance gains through faster memory clearing via SIMD, the actual computation of size classes is often negligible on modern, superscalar CPUs. Most agree that the primary benefit comes from removing conditional logic and reducing code size for better instruction cache performance. There is a consensus that the performance impact is more pronounced on simpler, anemic CPUs compared to high-end x86 processors.

top insight

The Go allocator's optimization focuses on transforming conditional size-class logic into constants within specialized functions, allowing the compiler to prune dead code and inline more aggressively. This approach reduces the cost of indirect calls and lookup table stalls that occur in dynamic runtime computation. However, a careful balance must be maintained to avoid excessive code size increases that would otherwise degrade instruction cache performance.

Generated by an LLM from the article and thread. Check the sources before relying on it.