Un bon point de départ est le grand livre The Science of Programming Matrix Computations de Robert A. van de Geijn et Enrique S. Quintana-Ortí. Ils fournissent une version téléchargeable gratuitement.
BLAS est divisé en trois niveaux:
Le niveau 1 définit un ensemble de fonctions d'algèbre linéaire qui n'opèrent que sur des vecteurs. Ces fonctions bénéficient de la vectorisation (par exemple de l'utilisation de SSE).
Les fonctions de niveau 2 sont des opérations matrice-vecteur, par exemple un produit matrice-vecteur. Ces fonctions pourraient être implémentées en termes de fonctions de niveau 1. Cependant, vous pouvez améliorer les performances de ces fonctions si vous pouvez fournir une implémentation dédiée qui utilise une architecture multiprocesseur avec mémoire partagée.
Les fonctions de niveau 3 sont des opérations comme le produit matrice-matrice. Encore une fois, vous pouvez les implémenter en termes de fonctions Level2. Mais les fonctions Level3 effectuent des opérations O (N ^ 3) sur les données O (N ^ 2). Donc, si votre plate-forme dispose d'une hiérarchie de cache, vous pouvez améliorer les performances si vous fournissez une implémentation dédiée optimisée pour le cache / compatible avec le cache . Ceci est bien décrit dans le livre. Le principal avantage des fonctions Level3 provient de l'optimisation du cache. Cette augmentation dépasse largement la deuxième augmentation du parallélisme et d'autres optimisations matérielles.
À propos, la plupart (voire la totalité) des implémentations BLAS hautes performances ne sont PAS implémentées dans Fortran. ATLAS est implémenté en C. GotoBLAS / OpenBLAS est implémenté en C et ses pièces critiques de performance dans Assembler. Seule l'implémentation de référence de BLAS est implémentée dans Fortran. Cependant, toutes ces implémentations BLAS fournissent une interface Fortran telle qu'elle peut être liée à LAPACK (LAPACK tire toutes ses performances de BLAS).
Les compilateurs optimisés jouent un rôle mineur à cet égard (et pour GotoBLAS / OpenBLAS, le compilateur n'a pas du tout d'importance).
IMHO no BLAS implémentation utilise des algorithmes comme l'algorithme Coppersmith – Winograd ou l'algorithme Strassen. Je ne suis pas exactement sûr de la raison, mais je suppose:
- Peut-être qu'il n'est pas possible de fournir une implémentation optimisée pour le cache de ces algorithmes (c'est-à-dire que vous perdriez plus que vous ne gagneriez)
- Ces algorithmes ne sont pas stables numériquement. Comme BLAS est le noyau de calcul de LAPACK, c'est un non-aller.
Modifier / mettre à jour:
Le nouveau document novateur sur ce sujet sont les papiers BLIS . Ils sont exceptionnellement bien écrits. Pour ma conférence "Bases du logiciel pour le calcul haute performance", j'ai implémenté le produit matrice-matrice en suivant leur article. En fait, j'ai implémenté plusieurs variantes du produit matrice-matrice. Les variantes les plus simples sont entièrement écrites en C brut et comportent moins de 450 lignes de code. Toutes les autres variantes optimisent simplement les boucles
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;
}
Les performances globales du produit matrice-matrice ne dépendent que de ces boucles. Environ 99,9% du temps est passé ici. Dans les autres variantes, j'ai utilisé des intrinsèques et du code assembleur pour améliorer les performances. Vous pouvez voir le tutoriel passant par toutes les variantes ici:
ulmBLAS: Tutoriel sur GEMM (produit Matrix-Matrix)
Avec les papiers BLIS, il devient assez facile de comprendre comment des bibliothèques comme Intel MKL peuvent obtenir de telles performances. Et pourquoi peu importe que vous utilisiez le stockage principal en ligne ou en colonne!
Les benchmarks finaux sont ici (nous avons appelé notre projet ulmBLAS):
Benchmarks pour ulmBLAS, BLIS, MKL, openBLAS et Eigen
Une autre modification / mise à jour:
J'ai également écrit un tutoriel sur la façon dont BLAS est utilisé pour des problèmes d'algèbre linéaire numérique comme la résolution d'un système d'équations linéaires:
Factorisation LU haute performance
(Cette factorisation LU est par exemple utilisée par Matlab pour résoudre un système d'équations linéaires.)
J'espère trouver le temps d'étendre le tutoriel pour décrire et démontrer comment réaliser une implémentation parallèle hautement évolutive de la factorisation LU comme dans PLASMA .
Ok, c'est parti: Codage d'une factorisation LU parallèle optimisée pour le cache
PS: J'ai également fait des expériences pour améliorer les performances d'uBLAS. Il est en fait assez simple de booster (ouais, jouer sur les mots :)) les performances d'uBLAS:
Expériences sur uBLAS .
Voici un projet similaire avec BLAZE :
Expériences sur BLAZE .