Resumo
Introdução
- A multiplicação de matrizes é um elemento essencial nas redes neurais modernas
- O NumPy alcança alto desempenho usando bibliotecas BLAS externas
- Este artigo explica como implementar uma multiplicação de matrizes de alto desempenho que seja simples, portátil e escalável
Desempenho do NumPy
- O NumPy usa OpenBLAS em CPUs AMD
- A medição de desempenho é calculada em FLOP/s
- O desempenho de thread única e multithread do NumPy foi medido em uma CPU Ryzen 7 7700
Limites teóricos
- Explica a hierarquia de memória da CPU e as extensões SIMD
- Teoricamente, é possível atingir 163 GFLOPS em thread única e 1203 GFLOPS em multithread
Implementação simples
- Explica o algoritmo básico de multiplicação de matrizes e mede o desempenho de uma implementação simples
- A implementação simples atinge 2,7 GFLOPS
Kernel
- Explica como resolver a multiplicação de matrizes dividindo o problema em subproblemas menores
- Otimiza o kernel usando instruções SIMD
- Com um kernel 16x6, atinge 147 GFLOPS
Mascaramento e empacotamento
- Explica como lidar com casos de borda para suportar tamanhos arbitrários de matrizes
- Otimiza o desempenho com mascaramento e empacotamento
- A nova implementação atinge 56 GFLOPS
Cache
- Explica o sistema de memória do cache da CPU
- Otimiza a reutilização de dados e o gerenciamento de cache aproveitando o cache
Opinião do GN⁺
- Este artigo é muito didático ao explicar passo a passo como implementar uma multiplicação de matrizes de alto desempenho
- É possível aprender métodos de otimização que aproveitam instruções SIMD e o cache da CPU
- Ajuda a entender o funcionamento interno de bibliotecas como o NumPy
- Outros projetos com funcionalidade semelhante incluem Intel MKL, OpenBLAS etc.
- Ao adotar novas tecnologias ou open source, é preciso considerar desempenho e portabilidade
1 comentários
Comentários do Hacker News
A maior parte do software não é otimizada, então há bastante margem para melhorar o desempenho
Os artigos citados no repositório do BLIS são materiais de referência para entender este tema
Instruções SIMD não são necessárias para a vetorização do microkernel
A maioria dos padrões de código não é totalmente específica ao hardware e por isso perde muito desempenho
É elogiável que tenham facilitado a repetição dos benchmarks
matmul.cleva 1,41 s quando compilado comgcc -O3, 1,47 s comclang -O2, e o NumPy leva 1,07 savx512seria mais rápidopthreadsem vez deomppara gerenciar explicitamente um pool de threads pode reduzir a sobrecargaHá dúvida se a implementação do NumPy realmente usa multithreading
Há curiosidade sobre o motivo de ter desempenho melhor que o OpenBLAS
Comparar Python de um lado e C do outro não é justo
A ineficiência na geração de máscaras incomoda
Há dúvida sobre a utilidade prática de fazer multithreading da própria multiplicação de matrizes
Menção ao tinyBLAS do jart