Single instruction multiple data

Un article de Wikipédia, l'encyclopédie libre.
(Redirigé depuis SIMD)
Aller à : navigation, rechercher
Page d'aide sur l'homonymie Pour les articles homonymes, voir Single.
plusieurs processeurs traitent plusieurs flux de données avec les mêmes instructions
Principe du mode SIMD.

Single Instruction on Multiple Data, ou SIMD, est une des quatre catégories d'architecture définies par la taxinomie de Flynn en 1966 et désigne un mode de fonctionnement des ordinateurs dotés de plusieurs unités de calcul fonctionnant en parallèle. Dans ce mode, la même instruction est appliquée simultanément à plusieurs données pour produire plusieurs résultats.

On utilise cette abréviation par opposition à SISD (Single Instruction on Single Data), le fonctionnement traditionnel, et MIMD (Multiple Instructions on Multiple Data), le fonctionnement avec plusieurs processeurs aux mémoires indépendantes.

Historique[modifier | modifier le code]

Défini par la taxinomie de Flynn en 1966, l'une des premières mis en application sera dans le supercalculateur Cray-1 en 1976[1].

Au début des années 1990, les micro-ordinateur Macintosh d'Apple et BeBox sont équipés de processeurs RISC PowerPC, ceux-ci comporte l'instruction fmadd (de l'anglais floating multiply-add, signifiant addition-mulitiplication flottante) et fmsub (de l'anglais floating multiply-substract, signifiant soustraction-multiplication flottante), capable de multiplier deux registres, de l'additionner ou soustraire à un troisième et de mettre le résultat dans un quatrième, ceux-ci pouvant être choisis à volonté sur les registres flottant double précision du FPU celles-ci, comme la majorité des autres instructions flottantes prennent trois à quatre cycles d’horloge pour leur exécution, mais jusqu'à trois peuvent être effectuées en parallèle, grâce au système de pipeline[2].

En 1997, AMD ajoute à ses microprocesseurs d'architecture x86 un SIMD appelé 3DNow!, c'est la première fois qu'un SIMD est ajouté à un processeur de technologie CISC. Intel suivra en 1999 avec la technologie SSE, incompatible avec 3DNow!.

Les VFP d'ARM est un processeur vectoriel introduit dans les SoC dans les années 2000, cela à permis de les introduire dans les téléphones mobiles et autres appareils mobiles de très faible consommation. En 2009, ARM introduit une évolution majeure avec la technologie NEON dans sa nouvelle gamme de processeurs ARM Cortex-A, avec le premier modèle, le Cortex-A8, augmentant les performances dans ce type d'appareil.

Utilisation[modifier | modifier le code]

Le modèle SIMD convient particulièrement bien aux traitements dont la structure est très régulière, comme c'est le cas pour le calcul matriciel. Généralement, les applications qui profitent des architectures SIMD sont celles qui utilisent beaucoup de tableaux, de matrices, ou de structures de données du même genre. On peut notamment citer les applications scientifiques, ou de traitement du signal.

Implémentation matérielle[modifier | modifier le code]

L'implémentation matérielle du paradigme SIMD peut se faire de diverses façons :

  • via l’utilisation d'instructions SIMD ;
  • par des processeurs vectoriels ;
  • par des streams processors ;
  • ou via des systèmes multicœeurs ou multiprocesseurs.

Dans les trois premiers cas, un seul processeur peut naturellement exécuter une opération identique sur des données différentes.

Dans le dernier cas, chaque processeur va effectuer une seule opération sur une donnée. Le parallélisme SIMD vient donc de l’utilisation de plusieurs processeurs.

Instructions SIMD[modifier | modifier le code]

Ces instructions sont des instructions qui peuvent effectuer plusieurs opérations en parallèles, sur des données différentes.

Les opérations en question peuvent être :

  • des opérations bit à bit, comme des et, ou, not bitwise ;
  • des additions ;
  • des soustractions ;
  • des multiplications ;
  • éventuellement des divisions ;
  • ou des opérations mathématiques plus complexes.
Exemple d'exécution d'une instruction d'addition vectorielle.

Toutes ces instructions SIMD travaillent sur un ensemble de données de même taille et de même type. Ces données sont rassemblées dans des espèces de blocs de données, d'une taille fixe, qu'on appelle un vecteur. Ces vecteurs contiennent plusieurs nombres entiers ou nombres flottants placés les uns à côté des autres.

Une instruction SIMD va traiter chacune des données du vecteur indépendamment des autres. Par exemple, une instruction d'addition SIMD va additionner ensemble les données qui sont à la même place dans deux vecteurs, et placer le résultat dans un autre vecteur, à la même place. Quand on exécute une instruction sur un vecteur, les données présentes dans ce vecteur sont traitées simultanément.

Tous les processeurs modernes contiennent des extensions à leur jeu d'instruction, comme le MMX, le SSE, etc. Ces extensions ont été ajoutées aux processeurs modernes pour pouvoir améliorer la vitesse de traitement sur les calculs. Les instructions SIMD sont composées notamment des jeux d'instructions :

Registres SIMD[modifier | modifier le code]

Les vecteurs traités par ces instructions sont souvent placés dans des registres à part, spécialisés dans le stockage des vecteurs. Ceux-ci ont souvent une taille assez importante, environ 128 à 256 bits.

Toutefois, certains processeurs utilisent leurs registres généraux pour stocker ces vecteurs. Ils ne disposent donc pas forcément de registres spécialisés, et les registres normaux sont utilisés pour maintenir des vecteurs. Les instructions SIMD travaillent alors sur les mêmes registres que leurs congénères non-SIMD. On appelle cette forme d'instructions SIMD du micro-SIMD.

Usage pour l'optimisation[modifier | modifier le code]

Les programmes qui sont optimisés avec ce genre d'instructions sont ceux qui demandent beaucoup de ressources processeur : compression de données, codec pour la lecture de son et/ou de vidéo, calcul sur de grands nombres entiers (cryptographie notamment), etc.

En général, ces instructions sont utilisées directement par les programmeurs. Ceux-ci écrivent des morceaux de code assembleur dans leurs programmes afin de pouvoir profiter au maximum des optimisations permises par les instructions SIMD. Ceux-ci commencent par développer un code générique qui fonctionnera partout. Quand l'algorithme est correct, ils écrivent une version spécialisée pour une extension d'un processeur donné. L'utilisation de ces instruction demande donc beaucoup de travail et des connaissances approfondies en assembleur.

Certains compilateurs et certaines bibliothèques permettent de bénéficier de ces optimisations sans coder en assembleur. On peut noter que le projet Mono par exemple profite de ces optimisations processeur si l'on utilise les classes adaptées. Mais il faut toutefois signaler que l'optimisation manuelle, effectuée par des programmeurs donne de meilleurs résultats que des optimisations effectuées par le compilateur[3].

Processeurs vectoriels[modifier | modifier le code]

Article détaillé : Processeur vectoriel.

Les processeurs vectoriels peuvent être vus comme des processeurs incorporant des instructions SIMD, avec quelques améliorations annexes. Par exemple, ces processeurs n'imposent pas de restrictions d'alignements pour les instructions SIMD d'accès mémoire. De plus, les instructions d'accès mémoire supportent des modes d'accès à la mémoire supplémentaires, comme les accès entrelacés ou en scatter-gather.

Stream Processing[modifier | modifier le code]

Le Stream Processing, ou calcul par flux, permet d'utiliser différents type d'unités pour le calcul, c'est ce que permet par exemple, le standard de bibliothèque de calcul OpenCL.

Paradigme logiciel[modifier | modifier le code]

Afin de faciliter d'utilisation des architectures SIMD, divers langages ont été inventés. Ces langages cherchent à rendre le parallélisme de donnée utilisable plus facilement par les compilateurs.

Dans les langages procéduraux actuels, les compilateurs ont du mal à déterminer si des instructions travaillent sur des données indépendantes ou non. En conséquence, les compilateur peuvent rater certaines opportunités d'utilisations d'instructions SIMD ou d'instructions vectorielles. C'est pour éviter au maximum ce genre de situations que certains langages SIMD ont été inventés.

Parmi ces langages, on peut citer :

  • Le langage CUDA. Ce langage permet l'utilisation des cartes graphiques pour le calcul numérique, et on y trouve de nombreuses instructions qui agissent sur plusieurs données en même temps.
  • Le standard de bibliothèque de calcul OpenCL, permet de paralléliser sur tous les processeurs disponibles du système ; CPU, GPU (ou gpGPU), DSP, SIMD, FPU, etc...
  • La bibliothèque OpenMP est une bibliothèque de calcul parallèle hétérogène, devenu un standard de fait sur les architectures comprenant plusieurs ordinateurs. Elle comporte depuis la version 4.0 des fonctions spécialisées dans l'utilisation des unités SIMD[4].
  • Les logiciels de calcul numérique, comme Matlab, Maple, Octave ou l'extension de Python SciPy, permettent aussi le calcul matriciel par des opérations SIMD.
  • On peut enfin citer la bibliothèque BLAS très utilisée en Fortran et en C/C++ pour l'algèbre linéaire. Cette bibliothèque fournit de nombreuses primitives de calcul matriciel et d'algèbre linéaire, qui opèrent toutes sur plusieurs données (des matrices ou des flottants).

Enfin, des compilateurs comme GCC ou LLVM (et CLANG), permettent l'auto-vectorisation de boucles de calcul sur la plupart des SIMD existant.

Références[modifier | modifier le code]

  1. (en) Use of SIMD Vector Operations to Accelerate Application Code Performance on Low-Powered ARM and Intel Platforms sur le site de l'université de Griffith, en Australie.
  2. (en)PowerPC 603e and EM603e RISC Microprocessor Family User's Manual, sur IBM.com – chapitre « 2.3.4.2.2 Floating-Point Multiply-Add Instructions », page 2-26 et chapitre « 6.4.3 Floating-Point Unit Execution Timing », page 6-17
  3. http://www.hardware.fr/articles/847-14/impact-assembleur-x264.html
  4. (en) OpenMP 4.0 Specifications Released