3.2 Triangularisation
3.2.4 TURBO : un algorithme pour la localité en mémoire
Nous avons vu dans la partie 3.2.3 que la gestion de la mémoire pouvait avoir des
réper-cussions sur le temps de calcul des implémentations, en particulier lorsque la totalité de la
mémoire vive disponible est allouée, et que la mémoire virtuelle sur disque (mémoire swap)
est utlisée. Dans de telles situations, l’ordonnancement des opérations effectuées
séquentiel-lement importe fortement : un algorithme traitant les données disséminées dans toute la
mé-moire multipliera les appels mémé-moire au disque dur, ralentissant ainsi l’exécution. A l’inverse,
un algorithme respectant la localité en mémoire des données qu’il manipule, limitera ce
ralen-tissement.
Nous étudions donc maintenant un algorithme produisant la décomposition LQUP, mais
dont les opérations sont organisées différemment, afin de mieux respecter la localité des
don-nées et de permettre une meilleure granularité. Il s’agit de l’algorithme TURBO, décrit dans
[37] et dont la figure 3.7 donne un aperçu du principe. Cet algorithme diffère de celui
dé-FIG. 3.7– Principe de l’algorithmeTURBO
crit dans la partie 3.2.2 en ce qu’il effectue un découpage récursif sur les lignes et sur les
colonnes. Ceci permet de conserver les proportions dans les dimensions des blocs au fil des
appels récursifs. A l’inverse, l’algorithme de la partie 3.2.2 produisait des blocs de plus en
plus rectangulaires. De plusTURBOpermet d’utiliser une structure récursive par blocs pour le
stockage de la matrice. Ces deux points assurent à TURBOun meilleur respect de la localité
des données en mémoire. Ceci est essentiel en parallélisme, mais aussi en calcul séquentiel,
comme nous allons le voir. On pourra se rapporter à l’article [61] sur le sujet des structures
matricielles récursives, et leurs avantages.
Nous rappelons d’abord brièvement le principe de l’algorithmeTURBO(voir [37] pour plus
de détails). A chaque niveau récursif, la matrice est partagée en quatre blocs. Puis cinq appels
récursifs triangularisent les blocs (U, V, C, DetZ)(dans l’ordre sur la figure 3.7), combinés
avec des calculs de compléments de Schur, utilisant six inversions triangulaires multiples et
quatre produits matriciels.
Nous avons implémenté une version simplifiée de cet algorithme : l’algorithme n’est
appli-qué que sur un seul niveau récursif, les niveaux inférieurs étant effectués parLQUP. En effet,
nous voulons montrer le bénéfice de cet algorithme pour le cas des matrices dépassant de peu
en taille la quantité de mémoire pouvant être allouée. Ainsi, le premier niveau récursif devrait
permettre de traiter plus efficacement les blocs de taille critique, et les niveaux inférieurs
trai-teront avec des blocs totalement alloués en mémoire vive, qui conviennent àLQUP. De plus, la
matrice Ln’est pas calculée dans notre implémentation, pour des raisons de simplicité. Cela
permet néanmoins d’obtenir un algorithme de calcul du rang ou du déterminant.
Dans la figure 3.8, nous comparons les vitesses de calcul de TURBO et de LQUP,
0
500
1000
1500
2000
2500
3000
0 2000 4000 6000 8000 10000 12000
Mfops
Matrix order
TURBO et LQUP pour le calcul du rang dans Z/101Z sur un P4−2.4Ghz−512Mo
(1) TURBO avec Givaro−ZpZ
(2) LQUP avec Givaro−ZpZ
(3) TURBO avec Modular<double>
(4) LQUP avec Modular<double>
FIG. 3.8– Comparaison des vitesses deTURBOetLQUPpour le calcul du rang
sant les deux représentations de corps fini modulaires : Givaro-ZpZet
Modular<dou-ble>, basées respectivement sur des entiers machines ou des flottants double précision. Les
matrices carrées d’ordre inférieur à 8000 peuvent être stockées intégralement dans les 512
Mo de mémoire vive. Alors LQUP est légèrement plus rapide queTURBO, sans doute
péna-lisé par un morcellement plus important des blocs (le produit matriciel, qui est l’opération de
base de ces algorithmes, est d’autant plus rapide que les blocs sont grands). La représentation
Givaro-ZpZutilise des entiers machine. Elle engendre donc des allocations mémoire
sup-plémentaires dans les produits matriciels pour la conversion vers des flottants afin d’utiliser la
routine BLAS dgemm. Ce surcoût en mémoire devient critique lorsquenest proche de 8000.
A partir de ce seuil, les performances de LQUP s’effondrent alors que celles de TURBO se
maintiennent sensiblement au même niveau jusqu’à n = 8500. Ceci s’explique par la moins
bonne localité en mémoire deLQUP: de grands blocs rectangulaires doivent être alloués pour
les produits matriciels, ce qui implique une forte utilisation de la mémoire virtuelle. A
l’op-posé, la meilleure localité en mémoire deTURBOlimite l’utilisation de la mémoire virtuelle et
à l’implémentation de rester efficace avec des dimensions supérieures.
Concernant la représentationModular<double>, il n’y a plus d’allocation de mémoire
temporaire, les deux algorithmes effectuent leurs calculs “en place”. L’absence de conversion
permet de gagner en vitesse pour n ≤ 8000. A partir de 8000, on constate le même
effon-drement en vitesse pourLQUP, mais aussi pourTURBOqui partagent la même complexité en
mémoire. Cependant, l’effondrement est moindre pour TURBO, ce que nous attribuons à sa
plus grande localité en mémoire, grâce à la structure de données récursive.
Ces comparaisons, plaident en faveur du développement des structures de données
récur-sives et des algorithmes respectueux de la localité en mémoire. Par ailleurs, lors de calculs
impliquant la mémoire virtuelle, ce n’est pas forcément la quantité totale d’allocations en
mémoire qu’il faut améliorer, mais plutôt la localité de données manipulées. En effet, c’est
l’implémentation deTURBOavecGivaro-ZpZqui est la plus efficace pourn≥8000. Nous
ÉTUDE SYSTÉMATIQUE SUR CERTAINS
NOYAUX D’ALGÈBRE LINÉAIRE
Les routines que nous avons étudiées aux chapitres 2 et 3 sont des briques de base sur
les-quelles reposera l’efficacité de l’ensemble des routines que nous décrivons. Pour la résolution
de plusieurs autres problèmes canoniques en algèbre linéaire, nous utilisons des algorithmes
récursifs par blocs, permettant de réduire ces problèmes à ces briques de base et de tirer ainsi
parti de leur efficacité. Nous décrivons ici en particulier les problèmes suivants :
– calcul du profil de rang,
– le calcul d’une base du noyau d’une matrice rectangulaire ou non inversible,
– le produit de matrices triangulaires,
– l’élévation au carré,
– la triangularisation de matrices symétriques,
– l’inversion de matrices (carrées, triangulaires ou même rectangulaires par l’inverse
géné-ralisé).
Tous ces problèmes sont résolus par des algorithmes de complexitéO(n
ω). En vue de leur
mise en pratique, il reste à préciser la constante du terme dominant dans leur complexité. Ceci
motive donc une description précise de chacun de ces algorithmes pour lesquels nous
don-nons l’expression de cette constante (en fonction deω etC
ω). Afin de réduire ces constantes,
nous proposons des algorithmes parfois différents de ceux utilisés pour la réduction au produit
matriciel. Certes ils ne sont probablement pas nouveaux dans la plupart des cas, mais l’étude
systématique de leur constante, et leur compilation au sein d’un chapitre comme celui-ci faisait
défaut dans la littérature.
4.1 Le profil de rang
Le profil de rang d’une matrice décrit la localisation des colonnes linéairement
indépen-dantes de cette matrice. On trouve par exemple dans [104, §2] la définition suivante :
Le profil de rang en colonne d’une matrice de rang r est la sous suite (j
1, . . . , j
r) de
(1, . . . , m)lexicographiquement minimale telle que les colonnesj
1, . . . , j
rsont de rangr.
On dit qu’une matrice a un profil de rang générique, si tous ses mineurs principaux sont
non nuls, ou de façon équivalente, si ses profils de rang en ligne et en colonne sont les suites
(1, . . . , r).
Le profil de rang d’une matrice peut s’obtenir à partir de sa forme échelonnée par ligne
(aussi appelée forme échelon) qui est largement étudiée dans [104, §2]. Le premier algorithme
tirant parti du produit matriciel rapide est dû à Keller-Gehrig [81] en 1985. On trouvera aussi
dans [13, §16.5] une étude détaillée sur la complexité de l’algorithme de Keller-Gehrig.
Storjo-hann propose dans [104] une version de l’algorithme de Gauss-Jordan par blocs afin d’obtenir
la forme échelon enO(nmr
ω−2). Cette méthode présente l’avantage d’inclure le rangr de la
matrice dans l’expression de la complexité.
Nous montrons dans la partie 4.1.1, que la décompositionLQUPpermet elle aussi d’obtenir
le profil de rang d’une matrice. A partir de cette décomposition, nous proposons dans la partie
4.1.2 une transformation basée sur des permutations, pour obtenir une matrice ayant un profil
de rang générique.
Dans le document
Algèbre linéaire exacte efficace : le calcul du polynôme caractéristique
(Page 81-85)