Vc est désormais en mode maintenance et n'est plus activement développé. Cependant, nous continuons d'examiner les demandes d'extraction avec des corrections de bugs de la communauté.
Vous pourriez être intéressé à passer à std-simd. GCC 11 inclut une version expérimentale de std::simd
dans le cadre de libstdc++, qui fonctionne également avec clang. Les fonctionnalités présentes dans Vc 1.4 et non présentes dans std-simd finiront par se transformer en Vc 2.0, qui dépend alors de std-simd .
Les générations récentes de processeurs, et de GPU en particulier, nécessitent des codes de données parallèles pour une efficacité totale. Le parallélisme des données nécessite que la même séquence d'opérations soit appliquée à différentes données d'entrée. Les CPU et les GPU peuvent ainsi réduire le matériel nécessaire au décodage et à la planification des instructions au profit d'unités plus arithmétiques et logiques, qui exécutent les mêmes instructions de manière synchrone. Sur les architectures CPU, cela est implémenté via des registres et des instructions SIMD. Un seul registre SIMD peut stocker N valeurs et une seule instruction SIMD peut exécuter N opérations sur ces valeurs. Sur les architectures GPU, N threads s'exécutent en parfaite synchronisation, alimentés par un seul décodeur/planificateur d'instructions. Chaque thread dispose d'une mémoire locale et d'un index donné pour calculer les décalages en mémoire pour les chargements et les magasins.
Les compilateurs C++ actuels peuvent effectuer une transformation automatique des codes scalaires en instructions SIMD (auto-vectorisation). Cependant, le compilateur doit reconstruire une propriété intrinsèque de l’algorithme qui a été perdue lorsque le développeur a écrit une implémentation purement scalaire en C++. Par conséquent, les compilateurs C++ ne peuvent pas vectoriser un code donné vers sa variante parallèle de données la plus efficace. Les boucles parallèles de données particulièrement volumineuses, s'étendant sur plusieurs fonctions ou même sur des unités de traduction, ne seront souvent pas transformées en code SIMD efficace.
La bibliothèque Vc fournit le chaînon manquant. Ses types permettent d'indiquer explicitement des opérations parallèles de données sur plusieurs valeurs. Le parallélisme est donc ajouté via le système de types. Des approches concurrentes affirment le parallélisme via de nouvelles structures de contrôle et par conséquent une nouvelle sémantique à l'intérieur du corps de ces structures de contrôle.
Vc est une bibliothèque de logiciels gratuits pour faciliter la vectorisation explicite du code C++. Il dispose d'une API intuitive et offre la portabilité entre différents compilateurs et versions de compilateur ainsi que la portabilité entre différents jeux d'instructions vectorielles. Ainsi une application écrite avec Vc peut être compilée pour :
Après qu'Intel ait abandonné la prise en charge de MIC avec ICC 18, Vc 1.4 a également supprimé sa prise en charge.
std::vector<Particle>
simdize
sur plusieurs std::vector<float>
. Notez l'importance de l'indicateur -march
par rapport à plain -mavx2 -mfma
.Commençons par le code de calcul d'un produit scalaire 3D à l'aide de flotteurs intégrés :
using Vec3D = std::array< float , 3 >;
float scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
En utilisant Vc, nous pouvons facilement vectoriser le code en utilisant le type float_v
:
using Vc::float_v
using Vec3D = std::array<float_v, 3 >;
float_v scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
Ce qui précède s'adaptera à des produits scalaires de 1, 4, 8, 16, etc. calculés en parallèle, en fonction des capacités du matériel cible.
À titre de comparaison, la même vectorisation utilisant les éléments intrinsèques Intel SSE est plus verbeuse et utilise la notation préfixe (c'est-à-dire les appels de fonction) :
using Vec3D = std::array<__m128, 3 >;
__m128 scalar_product (Vec3D a, Vec3D b) {
return _mm_add_ps ( _mm_add_ps ( _mm_mul_ps (a[ 0 ], b[ 0 ]), _mm_mul_ps (a[ 1 ], b[ 1 ])),
_mm_mul_ps (a[ 2 ], b[ 2 ]));
}
Ce qui précède ne s'adaptera pas à AVX, AVX-512, etc. et n'est pas non plus portable vers d'autres SIMD ISA.
cmake >= 3.0
Compilateur C++11 :
git clone https://github.com/VcDevel/Vc.git
cd Vc
git submodule update --init
$ mkdir build
$ cd build
$ cmake ..
Eventuellement, spécifiez un répertoire d'installation :
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..
Eventuellement, incluez la création des tests unitaires :
$ cmake -DBUILD_TESTING=ON ..
Sous Windows, si plusieurs versions de Visual Studio sont installées, vous pouvez en sélectionner une :
$ cmake -G " Visual Studio 16 2019 " ..
Voir cmake --help
pour une liste des générateurs possibles.
$ cmake --build . -j 16
$ cmake --install . # may require permissions
Sous Windows, vous pouvez également ouvrir Vc.sln
dans Visual Studio et créer/installer à partir de l'EDI.
La documentation est générée via doxygen. Vous pouvez créer la documentation en exécutant doxygen
dans le sous-répertoire doc
. Alternativement, vous pouvez trouver des versions nocturnes de la documentation à l'adresse :
Travailler sur l'intégration des fonctionnalités de Vc dans la bibliothèque standard C++.
Vc est publié selon les termes de la licence BSD à 3 clauses.