Cette fonctionnalité fait partie des propositions pour Harmony (ECMAScript7) et est donc expérimentale.
Cette spécification technique n'a pas encore été stabilisée, veuillez consulter le tableau de compatibilité pour plus d'informations sur les éventuelles différences entre les navigateurs. Il convient de noter qu'une fonctionnalité expérimentale peut voir sa syntaxe ou son comportement modifié dans le futur, en fonction des évolutions de la spécification.
SIMD est le sigle pour Single Instruction/Multiple Data qui est une classification d'architecture d'ordinateurs. SIMD permet d'effectuer une même opération sur plusieurs points de données, ce qui permet d'effectuer des traitements en parallèle et d'augmenter les performances (par exemple lors du traitement de vidéos, de simulations physique, de cryptanalyse, etc.).
Cette page, ainsi que les sous-pages associées constituent une documentation de référence pour l'API SIMD. Cet autre article sur les types SIMD décrit l'implémentation de cette API dans JavaScript de façon plus générale.
Description
L'API JavaScript SIMD comprend différents types et opérations. Les navigateurs fournissent des implémentations de cette API qui sont optimisées en fonction des composants matériels de l'environnement de l'utilisateur. Actuellement, SIMD est surtout conçu pour les plates-formes ARMv7 avec NEON et les plates-formes x86 avec SSE.
Les types pour l'API SIMD sont installés sur un module SIMD. À la différence de la plupart des objets globaux, SIMD n'est pas un constructeur. Aussi, on ne peut pas utiliser l'opérateur new ou appeler l'objet SIMD comme une fonction. L'ensemble des propriétés et méthodes de SIMD sont statiques (comme c'est le cas pour l'objet Math).
Aperçu
Un SIMD possède plusieurs voies (lanes). Pour un vector dont la longueur vaut 4, les voies seront appelées x, y, z, et w. Désormais, au lieu d'effectuer quatre opérations séparées sur chacune de ces voies, SIMD permet d'effectuer des opérations sur les 4 voies de façon simultanée. Cela nécessite moins d'opérations et entraîne donc une augmentation des performances et une meilleure efficacité énergétique comparé aux opérations scalaires (SISD). Les opérations SIMD ne peuvent pas être utilisées pour traiter différentes données de différentes façons. Avec le schéma suivant, on a une unique opération (l'addition) afin qu'elle puisse être effectuée avec SIMD :

Comparaison de SISD et SIMD
Addition arithmétique simple
var a = new SIMD.float32x4(1, 2, 3, 4); var b = new SIMD.float32x4(5, 6, 7, 8); var c = SIMD.float32x4.add(a,b); // float32x4[6,8,10,12]
Types de données
Tous les types de données SIMD sont immuables. Il n'est pas possible de les modifier directement. Ce qu'on peut faire, c'est effectuer des opérations afin de créer de nouveaux types de données SIMD immuables. Le schéma suivant illustre les différents types de données SIMD dans un registre SIMD sur 128 bits. L'API SIMD JavaScript actuelle possède cinq types différents avec des voies longues de 2, 4, 8 ou 16 bits.

Nombres de voies pour chaque type SIMD sur un registre 128 bits
SIMD.int8x16- 128 bits divisés en 16 voies qui stockent chacune des valeurs entières sur 8 bits.
SIMD.int16x8- 128 bits divisés en 8 voies qui stockent chacune des valeurs entières sur 16 bits.
SIMD.int32x4- 128 bits divisés en 4 voies qui stockent chacune des valeurs entières sur 32 bits.
SIMD.float32x4- 128 bits divisés en 4 voies qui stockent chacune des valeurs flottantes à précision simple.
SIMD.float64x2- 128 divisés en 2 voies qui stockent chacune des valeurs flottantes à précision double.
Constructeurs
En plus des constructeurs « simples » (tels que new SIMD.int32x4(1,2,3,4)), l'API SIMD fournit les constructeurs suivants.
SIMD.%type%.splat()- Crée un type de donnée SIMD dont toutes les voies sont définies avec une même valeur donnée.
SIMD.%type%.bool()- Crée un type de donnée SIMD avec des paramètres booléens ce qui permet de créer un masque de sélection explicite.
Note : Il est également possible d'effectuer une conversion à partir d'un type de donnée SIMD vers un autre.
Note : Les types SIMD ne fonctionnent pas avec new, en effet, les valeurs SIMD ne sont pas des objets classiques qu'on peut envelopper dans un constructeur (comme, par exemple,, pour les chaînes avec String(s) et new String(s)).
var v = new SIMD.float32x4(0,1,2,3); // TypeError: SIMD.float32x4 is not a constructor
Ici, on écrira juste :
var v = SIMD.float32x4(0,1,2,3);
Opérations
Pour effectuer des opérations avec les types SIMD, il est nécessaire d'utiliser des opérations SIMD qui fonctionnent sur ces types de données.
Note : L'ensemble des opérations SIMD ne sont pas disponibles pour tous les types SIMD. Pour plus de détails, voir les pages des différents types dans la référence.
Vérification des types SIMD
SIMD.%type%.check()- Renvoie une nouvelle instance si le paramètre passé est un type de donnée SIMD valide et si c'est le même que
%type%. Sinon, cette méthode lèvera une exceptionTypeError.
Accès et modification des voies
SIMD.%type%.extractLane()- Renvoie la valeur d'une voie donnée.
SIMD.%type%.replaceLane()- Renvoie une nouvelle instance dont la valeur de la voie a été remplacée.
Chargement et enregistrement à partir et vers un tableau typé
SIMD.%type%.load()- Renvoie une nouvelle instance dont les voies sont chargées avec les valeurs d'un tableau typé.
SIMD.%type%.store()- Enregistre un type de donnée SIMD dans un tableau typé.
Opérations arithmétiques
SIMD.%type%.abs()- Renvoie une nouvelle instance avec les valeurs absolues des voies.
SIMD.%type%.add()- Renvoie une nouvelle instance avec la somme des voies (
a + b). SIMD.%type%.div()- Renvoie une nouvelle instance dont les valeurs des voies sont les résultats de la division des voies (
a / b). SIMD.%type%.mul()- Renvoie une nouvelle instance avec la multiplication des voies (
a * b). SIMD.%type%.neg()- Renvoie une nouvelle instance avec les valeurs opposées des voies.
SIMD.%type%.reciprocalApproximation()- Renvoie une nouvelle instance avec une approximation des inverses des valeurs des voies.
SIMD.%type%.reciprocalSqrtApproximation()- Renvoie une nouvelle instance avec une approximation des inverses des racines carrées des valeurs des voies.
SIMD.%type%.sub()- Renvoie une nouvelle instance avec la soustraction des voies (
a - b). SIMD.%type%.sqrt()- Renvoie une nouvelle instance avec la racine carrée des valeurs des voies.
Mélange aléatoire et échange
SIMD.%type%.shuffle()- Renvoie une nouvelle instance dont les valeurs des voies ont été mélangées aléatoirement.
SIMD.%type%.swizzle()- Renvoie une nouvelle instance dont les valeurs des voies ont été échangées.
Minimum, maximum et encadrement
SIMD.%type%.clamp()- Renvoie une nouvelle instance dont les valeurs des voies sont ramenées entre une borne inférieure et une borne supérieure.
SIMD.%type%.max()- Renvoie une nouvelle instance qui contient les maximums des valeurs des voies.
SIMD.%type%.maxNum()- Renvoie une nouvelle instance qui contient les maximums des valeurs des voies et qui privilégie les nombres par rapport à
NaN. SIMD.%type%.min()- Renvoie une nouvelle instance avec les minimums des valeurs des voies.
SIMD.%type%.minNum()- Renvoie une nouvelle instance qui contient les minimums des valeurs des voies et qui privilégie les nombres par rapport à
NaN.
Sélections
SIMD.%type%.select()- Renvoie une nouvelle instance dont les valeurs des voies sont un mélange des différentes voies en fonction d'un masque de sélection.
SIMD.%type%.selectBits()- Renvoie une nouvelle instance dont les valeurs des voies sont un mélange de bits obtenu en fonction d'un masque de sélection.
Comparaisons
SIMD.%type%.equal()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea == b. SIMD.%type%.notEqual()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea != b. SIMD.%type%.lessThan()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea < b. SIMD.%type%.lessThanOrEqual()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea <= b. SIMD.%type%.greaterThan()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea > b. SIMD.%type%.greaterThanOrEqual()- Renvoie une nouvelle instance avec
trueoufalsepour chaque voie selon le résultat dea >= b.
Opérations logiques binaires
SIMD.%type%.and()- Renvoie une nouvelle instance dont les voies sont le résultat d'un ET logique sur les voies des instances fournies (
a & b). SIMD.%type%.or()- Renvoie une nouvelle instance dont les voies sont le résultat d'un OU logique sur les voies des instances fournies (
a | b). SIMD.%type%.xor()- Renvoie une nouvelle instance dont les voies sont le résultat d'un XOR logique sur les voies des instances fournies (
a ^ b). SIMD.%type%.not()- Renvoie une nouvelle instance dont les voies sont le résultat d'un NON logique sur les voies des instances fournies (
~a).
Opérations de décalage binaires
SIMD.%type%.shiftLeftByScalar()- Renvoie une nouvelle instance dont les valeurs des voies sont décalées à gauche d'un certain nombre de bits (
a << bits). SIMD.%type%.shiftRightArithmeticByScalar()- Renvoie une nouvelle instance dont les valeurs des voies sont décalées à droite (au sens arithmétique) d'un certain nombre de bits (
a >> bits). SIMD.%type%.shiftRightLogicalByScalar()- Renvoie une nouvelle instance dont les valeurs des voies sont décalées à droite (au sens logique) d'un certain nombre de bits (
a >>> bits).
Conversion
SIMD.%type%.fromFloat32x4()- Crée un nouveau type de donnée SIMD avec une conversion en flottant à partir d'un
float32x4. SIMD.%type%.fromFloat32x4Bits()- Crée un nouveau type de donnée SIMD avec une copie binaire à partir d'un
float32x4. SIMD.%type%.fromFloat64x2()- Crée un nouveau type de donnée SIMD avec une conversion en flottant à partir d'un
float64x2. SIMD.%type%.fromFloat64x2Bits()- Crée un nouveau type de donnée SIMD avec une copie binaire à partir d'un
float64x2. SIMD.%type%.fromInt32x4()- Crée un nouveau type de donnée SIMD avec une conversion entière à partir d'un
int32x4. SIMD.%type%.fromInt32x4Bits()- Crée un nouveau type de donnée SIMD avec une copie binaire à partir d'un
int32x4. SIMD.%type%.fromInt16x8Bits()- Crée un nouveau type de donnée SIMD avec une copie binaire à partir d'un
int16x8. SIMD.%type%.fromInt8x16Bits()- Crée un nouveau type de donnée SIMD avec une copie binaire à partir d'un
int8x16.
Spécifications
SIMD ne fait, à l'heure actuelle, partie d'aucun standard officiel (ni d'un brouillon). Pour le travail de standardisation en cours et les différentes implémentations de prothèses (polyfill) basées sur les tableaux typés, voir le dépot GitHub ecmascript_simd.
Compatibilité des navigateurs
| Fonctionnalité | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Support simple | Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.float32x4 |
Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.float64x2 |
Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.int8x16 |
Pas de support | Pas de support | Pas de support | Pas de support | Pas de support |
SIMD.int16x8 |
Pas de support | Pas de support | Pas de support | Pas de support | Pas de support |
SIMD.int32x4 |
Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
| Fonctionnalité | Android | Chrome pour Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Support simple | Pas de support | Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.float32x4 |
Pas de support | Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.float64x2 |
Pas de support | Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
SIMD.int8x16 |
Pas de support | Pas de support | Pas de support | Pas de support | Pas de support | Pas de support |
SIMD.int16x8 |
Pas de support | Pas de support | Pas de support | Pas de support | Pas de support | Pas de support |
SIMD.int32x4 |
Pas de support | Pas de support | Nightly build | Pas de support | Pas de support | Pas de support |
Notes de statut
Voir aussi
- Les types de données et les structures de données
- Les tableaux typés JavaScript
- La programmation SIMD en JavaScript, une présentation (en anglais) de Peter Jensen, Intel
- Animation du modèle de Mandelbrot utilisant SIMD, une démonstration de Peter Jensen, Intel.
- État des performance de SIMD.js dans Firefox, un billet (en anglais) de Benjamin Bouvier, Mozilla