Um bom ponto de partida é o grande livro The Science of Programming Matrix Computations, de Robert A. van de Geijn e Enrique S. Quintana-Ortí. Eles fornecem uma versão de download grátis.
O BLAS está dividido em três níveis:
O nível 1 define um conjunto de funções de álgebra linear que operam apenas em vetores. Essas funções se beneficiam da vetorização (por exemplo, do uso de SSE).
As funções de nível 2 são operações de vetor de matriz, por exemplo, algum produto de vetor de matriz. Essas funções podem ser implementadas em termos de funções de Nível 1. No entanto, você pode aumentar o desempenho dessas funções se puder fornecer uma implementação dedicada que faça uso de alguma arquitetura de multiprocessador com memória compartilhada.
As funções de nível 3 são operações como o produto matriz-matriz. Novamente, você pode implementá-los em termos de funções de Nível2. Mas as funções de Nível 3 realizam operações O (N ^ 3) em dados O (N ^ 2). Portanto, se sua plataforma tem uma hierarquia de cache, você pode aumentar o desempenho se fornecer uma implementação dedicada otimizada para cache / amigável para cache . Isso é muito bem descrito no livro. O principal impulso das funções do Nível 3 vem da otimização do cache. Esse aumento excede significativamente o segundo aumento do paralelismo e outras otimizações de hardware.
A propósito, a maioria (ou mesmo todas) as implementações de BLAS de alto desempenho NÃO são implementadas em Fortran. ATLAS é implementado em C. GotoBLAS / OpenBLAS é implementado em C e suas partes críticas de desempenho em Assembler. Apenas a implementação de referência do BLAS é implementada em Fortran. No entanto, todas essas implementações BLAS fornecem uma interface Fortran de forma que ele pode ser vinculado ao LAPACK (LAPACK ganha todo o seu desempenho do BLAS).
Compiladores otimizados desempenham um papel menor a este respeito (e para GotoBLAS / OpenBLAS o compilador não importa de todo).
A implementação de IMHO no BLAS usa algoritmos como o algoritmo Coppersmith – Winograd ou o algoritmo Strassen. Não tenho certeza sobre o motivo, mas este é o meu palpite:
- Talvez não seja possível fornecer uma implementação otimizada de cache desses algoritmos (ou seja, você perderia mais do que ganharia)
- Esses algoritmos não são numericamente estáveis. Como o BLAS é o kernel computacional do LAPACK, isso é impossível.
Editar / Atualizar:
O artigo novo e inovador para este tópico são os artigos BLIS . Eles são excepcionalmente bem escritos. Para minha palestra "Noções básicas de software para computação de alto desempenho", implementei o produto matriz-matriz seguindo seu artigo. Na verdade, implementei várias variantes do produto matriz-matriz. As variantes mais simples são inteiramente escritas em C simples e têm menos de 450 linhas de código. Todas as outras variantes apenas otimizam os loops
for (l=0; l<MR*NR; ++l) {
AB[l] = 0;
}
for (l=0; l<kc; ++l) {
for (j=0; j<NR; ++j) {
for (i=0; i<MR; ++i) {
AB[i+j*MR] += A[i]*B[j];
}
}
A += MR;
B += NR;
}
O desempenho geral do produto matriz-matriz depende apenas desses loops. Cerca de 99,9% do tempo é gasto aqui. Nas outras variantes, usei intrínsecos e código assembler para melhorar o desempenho. Você pode ver o tutorial passando por todas as variantes aqui:
ulmBLAS: Tutorial sobre GEMM (produto Matrix-Matrix)
Junto com os papéis do BLIS, torna-se bastante fácil entender como bibliotecas como Intel MKL podem obter tal desempenho. E por que não importa se você usa armazenamento principal de linha ou coluna!
Os benchmarks finais estão aqui (chamamos nosso projeto ulmBLAS):
Benchmarks para ulmBLAS, BLIS, MKL, openBLAS e Eigen
Outra edição / atualização:
Eu também escrevi um tutorial sobre como o BLAS é usado para problemas de álgebra linear numérica, como resolver um sistema de equações lineares:
Fatoração LU de alto desempenho
(Esta fatoração LU é, por exemplo, usada pelo Matlab para resolver um sistema de equações lineares.)
Espero encontrar tempo para estender o tutorial para descrever e demonstrar como realizar uma implementação paralela altamente escalonável da fatoração LU como no PLASMA .
Ok, aqui está: Codificando uma Fatoração de LU paralela otimizada de cache
PS: Eu também fiz alguns experimentos para melhorar o desempenho do uBLAS. Na verdade, é muito simples aumentar (sim, brincar com as palavras :)) o desempenho do uBLAS:
Experiências em uBLAS .
Aqui está um projeto semelhante com BLAZE :
Experiências em BLAZE .