IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

LLVM réfléchit à l'implémentation native des matrices pour faciliter les optimisations sur du code matriciel
Clang suit de près avec de nouvelles fonctions intégrées

Le , par dourouc05

188PARTAGES

9  0 
Un compilateur est souvent divisé en deux parties distinctes : une partie avant, qui lit un code source ; une partie arrière, qui écrit un code binaire pour une architecture donnée. Ces deux parties communiquent à l'aide d'une représentation intermédiaire (IR), sur laquelle bon nombre d'optimisations peuvent être effectuées. Un tel découpage facilite l'implémentation de nouveaux langages ou le ciblage de nouvelles plateformes. Pour qu'il soit efficace, le compilateur doit reposer sur une représentation intermédiaire de qualité, à un niveau d'abstraction bien choisi : ni trop élevée (l'IR correspondrait à un langage de programmation complet), ni trop basse (l'IR serait alors un assembleur pour une architecture précise). L'IR doit être un compromis entre une grande possibilité d'optimisation du code, une simplicité d'écriture du générateur de code binaire (qui a déjà beaucoup de choses à gérer avec les détails de l'architecture cible, comme l'utilisation des registres du processeur ou les optimisations spécifiques) et une indépendance de la plateforme ciblée (pour que les optimisations effectuées sur l'IR soient utiles à plusieurs plateformes).

La représentation intermédiaire LLVM IR est utilisée par la famille de compilateurs de l'écosystème LLVM, comme Clang ou Flang. Ses développeurs la décrivent comme un langage d'assemblange pour une plateforme virtuelle (d'où l'acronyme LLVM : low-level virtual machine), avec toutefois la notion de fonction (ce qui permet notamment d'écrire une valeur de retour : la gestion des conventions d'appel peut alors dépendre de la plateforme cible, ce qui est par exemple le cas en C et C++). Elle dispose d'une série de types de base : des scalaires, évidemment, des agrégats, c'est-à-dire des ensembles de valeurs stockées ensemble (comme une structure ou un objet), mais aussi des vecteurs à longueur fixe ou variable, qui servent à donner aux passes d'optimisation autant d'informations que possible sur le code (et donc à générer un code binaire aussi efficace que possible, in fine, avec l'utilisation des instructions SIMD disponibles sur le processeur visé).

Dès 2018, certains développeurs d'Apple travaillant sur LLVM proposent d'ajouter un nouveau type de structure de données dans cette représentation intermédiaire : les matrices. L'IR disposerait aussi d'une série de fonctions intrinsèques pour travailler sur ces matrices, comme l'extraction et la mise à jour d'une valeur, un produit entre matrices ou entre une matrice et un vecteur. L'avantage serait d'apporter plus d'informations au générateur de code binaire : le compilateur pourrait alors fournir de bien meilleures garanties de vectorisation du code (voire d'utilisation des instructions matricielles, par exemple celles présentes dans l'architecture ARM v8.6) ; de même, il pourrait s'arranger pour éviter des écritures en mémoire trop fréquentes, laissant les valeurs nécessaires dans les registres du processeur. Il pourrait aussi décider de la meilleure manière de représenter la matrice en mémoire : soit ligne par ligne, soit colonne par colonne, soit comme une matrice creuse, selon le type d'accès le plus fréquent. Le générateur de code pourrait aussi décider de remplir la mémoire entre les lignes ou les colonnes, de telle sorte que chaque ligne ou chaque colonne soit bien alignée.

En détail, la proposition porte sur quatre types de fonction intrinsèques : transposition, multiplication, lecture et écriture (y compris avec décalages). L'idée d'un type entièrement spécifique aux matrices n'a pas été très appréciée de tous les développeurs (à cause de la complexité de l'opération), c'est pourquoi elles sont plutôt implémentées comme des vecteurs : les dimensions de la matrice sont passées en argument aux fonctions intrinsèques.

Clang suit assez rapidement la tendance et prévoit déjà d'utiliser ces nouvelles fonctionnalités. Les matrices seraient indiquées par un attribut, matrix_type(lignes, colonnes), où les dimensions de la matrice seraient constantes ; cet attribut porterait sur une variable de type tableau, contenant au moins autant d'éléments que la matrice déclarée. Le compilateur fournirait une série d'opérations intégrées correspondant aux fonctions intrinsèques.

Source : liste de diffusion LLVM (proposition d'origine, proposition reformulée, détails d'implémentation pour Clang), premier commit.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Rep.Movs
Membre habitué https://www.developpez.com
Le 26/12/2019 à 16:01
Ayant codé des calculs matriciels en fortran + MPI/OpenMP sur 64 processeurs en 2000, je doit avouer que j’ai été décontenancé de voir que les langages pour les cartes graphiques n’avaient pas à leur sortie de méta-structure de type «matrice» autre que du 4x4.
En 2000, arriver aux performances du compilateur fortran pour le calcul matriciel était extrêmement compliqué (surtout face à la simplicité du programme écrit en Fortran, à peine décoré de quelques directives pour donner des indices au compilateur concernant ce qui était à paralléliser et ce qui était constant ou variable), donc je me suis limité à ce compilateur (alors que sur plein d’autres programmes classiques, le portage en C avait amené de meilleures performances).

Si la LLVM le prend en compte, c’est un bon début, mais ensuite il faudra ajouter ce genre de primitives au niveau des langages et enfin que les programmeurs s’en emparent… Ça ne me semble pas pour tout de suite!
1  0