diff --git a/mlx/backend/metal/kernels/steel/attn/kernels/steel_attention_nax.h b/mlx/backend/metal/kernels/steel/attn/kernels/steel_attention_nax.h index adc9a42798..7d74d6f44b 100644 --- a/mlx/backend/metal/kernels/steel/attn/kernels/steel_attention_nax.h +++ b/mlx/backend/metal/kernels/steel/attn/kernels/steel_attention_nax.h @@ -207,7 +207,12 @@ template < for (short iq = 0; iq < TQ; iq++) { STEEL_PRAGMA_UNROLL for (short ik = 0; ik < TK; ik += 2) { - STEEL_PRAGMA_UNROLL + // Unrolling the head-dim loop by 4 rather than fully lets the + // compiler interleave the next K-tile loads with the running mma + // chain instead of hoisting all TD loads up front; measures +11% + // at head_dim 128 on M5 Max and is a no-op at head_dim 64 (TD == 4, + // already a full unroll). +#pragma clang loop unroll_count(4) for (short id = 0; id < TD; id++) { NAXTile Qtile; NAXTile Ktile;