4096³ GEMM on NVIDIA + Apple — what the numbers look like
The cleanest way to feel BLAS's value is to run the same logical operation on both ecosystems and read the throughput numbers side by side.
| Level | RTX 4090 (FP32) | M3 Ultra (FP32) | M3 Ultra (FP16) |
|---|---|---|---|
| BLAS-1 (AXPY) | 20 GF/s | 5 GF/s | — |
| BLAS-2 (GEMV) | 0.44 GF/s | 279 GF/s (GPU) | 1,136 GF/s |
| BLAS-3 (GEMM) | 2.32 TF/s (non-Tensor-Core) | 13.89 TF/s | 18.15 TF/s |
Three things to read from this table:
- BLAS-1 is awful on GPU. You see double-digit GF/s on hardware capable of TF/s — bandwidth-bound, no reuse, no chance. cuBLAS detects this and runs it on the host or skips Tensor Cores.
- The CUDA FP32 GEMM here uses the non-tensor path for a fair comparison. Enable Tensor Core FP16 via
cublasGemmExwithCUBLAS_GEMM_DEFAULT_TENSOR_OPand the 4090 jumps past 30 TF/s. - M3 Ultra GEMM crushes because the matrix coprocessor is fed by huge unified memory bandwidth. Tested at 4096³.
Intensity trends are platform-agnostic: BLAS-1 → bandwidth-bound, BLAS-3 → compute-bound. The absolute numbers vary; the shape of the picture doesn't.