• Aucun résultat trouvé

TURBO : un algorithme pour la localité en mémoire

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

r

sont 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.