85.3 GFlops: Optimizing FP32 Matrix Multiplication on a Single AMD Zen 3 Core
Introduction
Uma exploração sistemĂĄtica de otimização de multiplicação de matrizes usando AVX2/FMA em C++ intrinsics, alcançando 63,5% do pico teĂłrico de 134,4 GFLOPS em um AMD Ryzen 5 5500. Este repositĂłrio contĂ©m o cĂłdigo fonte, resultados e anĂĄlise de um estudo aprofundado sobre otimização de multiplicação de matrizes (GEMM) para precisĂŁo simples (FP32) em uma Ășnica nĂșcleo da microarquitetura AMD Zen 3. Foram testadas 28 configuraçÔes distintas (modelos MX01 a MX28) que combinam tĂ©cnicas como:
- Cache blocking (tiling) em trĂȘs nĂveis (L1, L2, L3)
- Register blocking (2, 4 e 8 linhas)
- Encadeamento de instruçÔes FMA (chain1 a chain6)
- EstratĂ©gias de empacotamento (sem packing, transposição, Bâpack onâtheâfly)
- Alinhamento de memĂłria (32 bytes)
- Prefetching por software
- Stores nĂŁo temporais (stream stores)
O melhor modelo, MX24, sustentou 85.30 GFLOPS, superando a implementação ingĂȘnua por um fator de 56,5Ă e igualando o desempenho de bibliotecas otimizadas como AMD AOCL e OpenBLAS.
Best Models
| Modelo | Descrição | GFLOPS | % Pico |
|---|---|---|---|
| MX24 | 4âlinhas + chain4 + Bâpack (BK=256) | 85.30 | 63.5% |
| MX22 | 4âlinhas + chain4 + Bâpack (BK=128) | 84.10 | 62.6% |
| MX23 | 4âlinhas + chain4 + Bâpack (BK=64) | 82.93 | 61.7% |
| MX16 | 4âlinhas + chain4 + alinhado (sem pack) | 72.58 | 54.0% |
| MX20 | 4âlinhas + chain4 + Bá” (transposta) | 79.21 | 58.9% |
| MX18 | 4âlinhas + chain4 + prefetch | 79.75 | 59.3% |
âčïž O pico teĂłrico Ă© calculado como 2 portas FMA Ă 8 floats Ă 2 ops Ă 4,2 GHz = 134,4 GFLOPS.
Technical Details
Cache Blocking (Tiling)
BI, BJ, BK ajustados para manter os blocos dentro das caches L1 (32 KB), L2 (512 KB) e L3 (16 MB). O melhor BK encontrado foi 256, que maximiza a reutilização sem estourar a L2.
Register Blocking
- Acumuladores de C mantidos em registradores YMM (16 disponĂveis).
- 4 linhas proporcionou o melhor equilĂbrio: apesar de exigir spill (16 registradores extras), a reutilização de A compensa o custo.
FMA Chaining
A latĂȘncia da instrução FMA no Zen 3 Ă© de 4 ciclos. O encadeamento chain4 (4 acumuladores independentes) esconde essa latĂȘncia, atingindo utilização mĂĄxima das duas portas FMA.
Empacotamento (Packing)
- Bâpack onâtheâfly: copia blocos de B (BKĂBJ) para um buffer contĂguo, convertendo acessos nĂŁo contĂguos em sequenciais.
- Supera a transposição completa (que polui a L3) e o acesso direto (que sofre com misses de TLB).
Alinhamento
Alocação com _mm_malloc(..., 32) para uso de instruçÔes vmovaps (alinhadas), trazendo ganho de ~5%.
Prefetching
O uso de _mm_prefetch reduziu o desempenho em ~8%, pois o hardware prefetcher do Zen 3 jå é eficiente para padrÔes de streaming.
Stores NĂŁo Temporais
_mm256_stream_ps foi catastrĂłfico (1,24 GFLOPS), pois C Ă© lidoâmodificadoâescrito, e a instrução invalida a linha de cache a cada escrita.
Repository Structure
zen3-gemm/
âââ README.md
âââ src/
â âââ mx85.c # CĂłdigo completo com todos os 28 modelos + benchmark
âââ docs/
â âââ artigo_en.tex # Artigo cientĂfico completo (LaTeX)
â âââ resultados/ # Logs de saĂda do benchmark
â âââ mx85_benchmark.txt
â âââ mx85_output8.txt
âââ build/
âââ Makefile # (opcional) para compilação simples
Requirements
- Processador com suporte a AVX2 e FMA (ex: AMD Zen, Intel Haswell ou superior)
- Sistema operacional Windows (10/11) ou Linux
- Compilador GCC 12.2+ (MinGWâw64 no Windows) ou equivalente com suporte a intrinsics AVX2
- MemĂłria suficiente para matrizes 2048Ă2048 (â 48 MB para as trĂȘs matrizes)
Compilation and Usage
No diretĂłrio src/, execute:
gcc -O3 -mavx2 -mfma -march=native -funroll-loops -frename-registers -o mx85.exe mx85.c
Flags importantes:
-mavx2 -mfma -march=native- habilita instruçÔes SIMD e otimiza para a CPU atual.-funroll-loops- desenrola laços internos.-frename-registers- melhora a alocação de registradores (reduz spills).
Em seguida:
./mx85.exe
O programa:
- Aplica afinidade de thread ao nĂșcleo 0 (Windows) e prioridade alta.
- Executa cada modelo 3 vezes (warmup) + 15 vezes medidas.
- Gera dois arquivos de saĂda:
mx85_benchmark.txt- ranking completo e validação;mx85_validate.txt- erros mĂĄximos versus implementação de referĂȘncia.
Para testar apenas um modelo especĂfico, vocĂȘ pode modificar a função main() para chamar diretamente a função desejada (ex: mx24(A, B, C, N)). Ou, para matrizes de outros tamanhos, altere a constante N (linha ~230).
Complete Benchmark Results
Abaixo estĂŁo todos os 28 modelos testados, com GFLOPS medidos e porcentagem do pico teĂłrico.
| Pos | Modelo | Descrição | GFLOPS | % Pico |
|---|---|---|---|---|
| 1 | MX24 | 4âlinhas + chain4 + Bâpack BK=256 | 85.30 | 63.5% |
| 2 | MX22 | 4âlinhas + chain4 + Bâpack BK=128 | 84.10 | 62.6% |
| 3 | MX23 | 4âlinhas + chain4 + Bâpack BK=64 | 82.93 | 61.7% |
| 4 | MX25 | 4âlinhas + chain4 + Bâpack + prefetch | 83.15 | 61.9% |
| 5 | MX20 | 4âlinhas + chain4 + Bá” (transposta) | 79.21 | 58.9% |
| 6 | MX18 | 4âlinhas + chain4 + prefetch | 79.75 | 59.3% |
| 7 | MX17 | 4âlinhas + chain4 + sem pack | 78.80 | 58.6% |
| 8 | MX16 | 4âlinhas + chain4 + alinhado | 72.58 | 54.0% |
| 9 | MX15 | 4âlinhas + chain3 + Bâpack | 62.34 | 46.4% |
| 10 | MX14 | 4âlinhas + chain2 + Bâpack | 55.76 | 41.5% |
| 11 | MX13 | 2âlinhas + chain4 + Bâpack | 53.58 | 39.9% |
| 12 | MX12 | 2âlinhas + chain3 + Bâpack | 50.56 | 37.6% |
| 13 | MX11 | 4âlinhas + chain2 + alinhado | 47.15 | 35.1% |
| 14 | MX08 | 2âlinhas + chain4 + BK=128 | 45.04 | 33.5% |
| 15 | MX07 | 2âlinhas + chain3 + sem Bt | 43.52 | 32.4% |
| 16 | MX05 | 2âlinhas + chain2 + Bt | 41.93 | 31.2% |
| 17 | MX19 | 4âlinhas + chain5 + alinhado | 42.07 | 31.3% |
| 18 | MX06 | 2âlinhas + chain1 + prefetch | 42.54 | 31.7% |
| 19 | MX04 | 4âlinhas + chain1 + Bt | 40.04 | 29.8% |
| 20 | MX03 | 2âlinhas + chain1 + Bt | 39.34 | 29.3% |
| 21 | MX02 | 2âlinhas + chain1 + jâblock | 37.60 | 28.0% |
| 22 | MX01 | Bt + 2Dtile + 8acc (baseline) | 35.16 | 26.2% |
| 23 | MX10 | 4âlinhas + chain6 + Bt | 14.26 | 10.6% |
| 24 | MX26 | 8âlinhas + chain4 + Bâpack | 12.24 | 9.1% |
| 25 | MX28 | 4âlinhas + chain4 + dual16 | 13.75 | 10.2% |
| 26 | MX27 | 4âlinhas + chain4 + Câinâregs | 9.13 | 6.8% |
| 27 | MX09 | BI=128, BK=256 + chain4 | 8.38 | 6.2% |
| 28 | MX21 | 4âlinhas + chain4 + stream stores | 1.24 | 0.9% |
Analysis of Low-Performance Models
| Modelo | Técnica | GFLOPS | Causa |
|---|---|---|---|
| MX21 | Stores nĂŁo temporais | 1.24 | C Ă© lidoâmodificadoâescrito; cada store invalida a cache, forçando reloads da DRAM. |
| MX26 | 8 linhas em registradores | 12.24 | Necessita 64 registradores YMM; 48 são spilled, dominando o tempo de execução. |
| MX27 | Câinâregs atravĂ©s de kâblock | 9.13 | MantĂ©m acumuladores vivos por muitas iteraçÔes, aumentando pressĂŁo de registradores. |
| MX09 | BI=128, BK=256 | 8.38 | O working set (128Ă256Ă4 = 128 KB) excede a L1, causando muitas misses. |
| MX10 | Chain6 | 14.26 | Cadeia longa demais; falta de registradores força spilling excessivo. |
Validation
Todos os modelos foram validados contra uma implementação de referĂȘncia (escolar ijk). Os trĂȘs melhores modelos (MX24, MX22, MX23) apresentaram erro mĂĄximo absoluto = 0.0 (bitâidĂȘnticos), pois a ordem de acumulação Ă© preservada. Os demais modelos apresentaram erros da ordem de 1e-6, dentro do esperado para aritmĂ©tica de ponto flutuante.
Citation
Se utilizar este trabalho em suas pesquisas, por favor cite o artigo associado:
@article{housl2025gemm,
title={85.30 GFLOPS Single-Core FP32 Matrix Multiplication on AMD Zen 3},
author={Housl},
journal={arXiv preprint},
year={2025}
}
Contributions
ContribuiçÔes sĂŁo bemâvindas! Sintaâse Ă vontade para abrir issues ou pull requests com melhorias, novos modelos ou adaptaçÔes para outras arquiteturas.
License
Este projeto estĂĄ disponĂvel sob a MIT License. Isso significa que vocĂȘ pode usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e/ou vender cĂłpias do software, desde que mantenha o aviso de direitos autorais e a permissĂŁo. Veja o arquivo LICENSE para os termos completos.
Contact
Autor: Lucas Lima Freitag
Eâmail: fr**********@academico.ifrn.edu.br
Papel: Autor
Afiliação: Universidade Federal do Rio Grande do Norte (UFRN)
ORCID: 0009-0006-8849-5619
Divirtaâse otimizando! đ Se tiver dĂșvidas, sugestĂ”es ou quiser compartilhar seus prĂłprios resultados, fique Ă vontade para entrar em contato.
Comments
No comments yet. Start the discussion.