Emballages C ++ pour les intrinsèques SIMD
SIMD (instruction unique, données multiples) est une caractéristique des microprocesseurs disponible depuis de nombreuses années. Les instructions SIMD effectuent une seule opération sur un lot de valeurs à la fois, et fournissent ainsi un moyen d'accélérer considérablement l'exécution du code. Cependant, ces instructions diffèrent entre les fournisseurs de microprocesseurs et les compilateurs.
xsimd fournit un moyen unifié pour utiliser ces fonctionnalités pour les auteurs de la bibliothèque. À savoir, il permet la manipulation de lots de nombres avec les mêmes opérateurs arithmétiques que pour les valeurs uniques. Il fournit également une implémentation accélérée de fonctions mathématiques communes fonctionnant sur des lots.
Au-delà de Xtensor, XSIMD a été adopté par de grands projets open source, tels que Mozilla Firefox, Apache Arrow, Pythran et Krita.
Le projet XSIMD a commencé avec une série d'articles de blog de Johan Mabille sur la façon de mettre en œuvre des emballages pour les intrinsictes SIMD. Les archives du blog se trouvent ici: le scientifique C ++. La conception décrite dans les articles est restée proche de l'architecture réelle de XSIMD jusqu'à la version 8.0.
Les fonctions mathématiques sont une mise en œuvre légère des algorithmes implémentés à l'origine dans le projet Boost.SIMD maintenant déprécié.
xsimd nécessite un compilateur conforme C ++ 11. Les compilateurs C ++ suivants sont pris en charge:
| Compilateur | Version |
|---|---|
| Microsoft Visual Studio | MSVC 2015 Update 2 et plus |
| G ++ | 4.9 et plus |
| bruit | 4.0 et plus |
Les extensions de jeu d'instructions SIMD suivantes sont prises en charge:
| Architecture | Extensions de jeu d'instructions |
|---|---|
| x86 | SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, FMA3 + SSE, FMA3 + AVX, FMA3 + AVX2 |
| x86 | AVX512BW, AVX512CD, AVX512DQ, AVX512F (GCC7 et plus) |
| x86 AMD | FMA4 |
| BRAS | NEON, NEON64, SVE128 / 256/512 (taille du vecteur fixe) |
| Webassembly | Wasm |
| RISC-V | RISC-V128 / 256/512 (taille du vecteur fixe) |
Un package pour XSIMD est disponible sur le gestionnaire de packages Mamba (ou Conda).
mamba install -c conda-forge xsimdUn package pour XSIMD est disponible sur le Spack Package Manager.
spack install xsimd
spack load xsimdVous pouvez l'installer directement à partir des sources avec CMake:
cmake -D CMAKE_INSTALL_PREFIX=your_install_prefix .
make install Pour commencer avec l'utilisation xsimd , consultez la documentation complète
http://xsimd.readthedocs.io/
xsimd a une dépendance facultative sur la bibliothèque XTL:
xsimd | xtl (facultatif) |
|---|---|
| maître | ^ 0.7.0 |
| 12.x | ^ 0.7.0 |
| 11.x | ^ 0.7.0 |
| 10.x | ^ 0.7.0 |
| 9.x | ^ 0.7.0 |
| 8.x | ^ 0.7.0 |
La dépendance sur xtl est requise si vous souhaitez prendre en charge la vectorisation pour xtl::xcomplex . Dans ce cas, vous devez créer votre projet avec C ++ 14 Assistance activée.
La version 8 de la bibliothèque est une réécriture complète et il existe quelques légères différences avec les versions 7.x. Un guide de migration sera bientôt disponible. En attendant, les exemples suivants montrent comment utiliser les versions 7 et 8 de la bibliothèque?
Voici un exemple qui calcule la moyenne de deux ensembles de 4 valeurs de points flottants doubles, en supposant que l'extension AVX est prise en charge:
# include < iostream >
# include " xsimd/xsimd.hpp "
namespace xs = xsimd;
int main ( int argc, char * argv[])
{
xs::batch< double , xs::avx2> a = { 1.5 , 2.5 , 3.5 , 4.5 };
xs::batch< double , xs::avx2> b = { 2.5 , 3.5 , 4.5 , 5.5 };
auto mean = (a + b) / 2 ;
std::cout << mean << std::endl;
return 0 ;
} N'oubliez pas d'activer l'extension AVX lors de la construction de l'exemple. Avec GCC ou Clang, cela se fait avec l'indicateur -mavx , sur MSVC, vous devez passer l'option /arch:AVX .
Cet exemple de sortie:
( 2.0 , 3.0 , 4.0 , 5.0 )Le même calcul fonctionnant sur des vecteurs et en utilisant le jeu d'instructions le plus performant disponible:
# include < cstddef >
# include < vector >
# include " xsimd/xsimd.hpp "
namespace xs = xsimd;
using vector_type = std::vector< double , xsimd::aligned_allocator< double >>;
void mean ( const vector_type& a, const vector_type& b, vector_type& res)
{
std:: size_t size = a. size ();
constexpr std:: size_t simd_size = xsimd::simd_type< double >::size;
std:: size_t vec_size = size - size % simd_size;
for (std:: size_t i = 0 ; i < vec_size; i += simd_size)
{
auto ba = xs::load_aligned (&a[i]);
auto bb = xs::load_aligned (&b[i]);
auto bres = (ba + bb) / 2 .;
bres. store_aligned (&res[i]);
}
for (std:: size_t i = vec_size; i < size; ++i)
{
res[i] = (a[i] + b[i]) / 2 .;
}
}La construction des tests nécessite Cmake.
cmake est disponible en tant que package pour la plupart des distributions Linux. En outre, ils peuvent également être installés avec le gestionnaire de packages conda (même sur Windows):
conda install -c conda-forge cmake Une fois cmake installé, vous pouvez construire et exécuter les tests:
mkdir build
cd build
cmake ../ -DBUILD_TESTS=ON
make xtest Dans le contexte d'une intégration continue avec Travis CI, les tests sont exécutés dans un environnement conda , qui peut être activé avec
cd test
conda env create -f ./test-environment.yml
source activate test-xsimd
cd ..
cmake . -DBUILD_TESTS=ON
make xtestLa documentation de XSIMD est construite avec trois outils
Alors que le doxygen doit être installé séparément, vous pouvez installer Breathe en tapant
pip install breathe La respiration peut également être installée avec conda
conda install -c conda-forge breatheEnfin, construisez la documentation avec
make html du sous-répertoire docs .
Nous utilisons un modèle de droit d'auteur partagé qui permet à tous les contributeurs de maintenir le droit d'auteur sur leurs contributions.
Ce logiciel est sous licence en vertu de la licence de clause BSD-3. Voir le fichier de licence pour plus de détails.