Envoltorios C ++ para intrínsecs SIMD
SIMD (instrucción única, datos múltiples) es una característica de los microprocesadores que ha estado disponible durante muchos años. Las instrucciones SIMD realizan una sola operación en un lote de valores a la vez y, por lo tanto, proporcionan una forma de acelerar significativamente la ejecución del código. Sin embargo, estas instrucciones difieren entre proveedores y compiladores de microprocesadores.
xsimd proporciona un medio unificado para usar estas características para los autores de la biblioteca. A saber, permite la manipulación de lotes de números con los mismos operadores aritméticos que para valores individuales. También proporciona la implementación acelerada de funciones matemáticas comunes que operan en lotes.
Más allá de Xtensor, XSIMD ha sido adoptado por los principales proyectos de código abierto, como Mozilla Firefox, Apache Arrow, Pythran y Krita.
El proyecto XSIMD comenzó con una serie de artículos de blog de Johan Mabille sobre cómo implementar envoltorios para intrínsectos SIMD. Los archivos del blog se pueden encontrar aquí: el científico C ++. El diseño descrito en los artículos permaneció cerca de la arquitectura real de XSIMD hasta la versión 8.0.
Las funciones matemáticas son una implementación liviana de los algoritmos implementados originalmente en el proyecto ahora despreciado.
xsimd requiere un compilador compatible con C ++ 11. Se admiten los siguientes compiladores de C ++:
| Compilador | Versión |
|---|---|
| Microsoft Visual Studio | Actualización de MSVC 2015 2 y superior |
| G ++ | 4.9 y superior |
| sonido metálico | 4.0 y superior |
Se admiten las siguientes extensiones de instrucciones SIMD:
| Arquitectura | Extensiones establecidas de instrucciones |
|---|---|
| x86 | SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, FMA3+SSE, FMA3+AVX, FMA3+AVX2 |
| x86 | AVX512BW, AVX512CD, AVX512DQ, AVX512F (GCC7 y superior) |
| x86 amd | FMA4 |
| BRAZO | Neon, Neon64, SVE128/256/512 (tamaño de vector fijo) |
| Aviso web | Wasm |
| RISC-V | RISC-V128/256/512 (tamaño de vector fijo) |
Un paquete para XSIMD está disponible en el Administrador de paquetes Mamba (o Conda).
mamba install -c conda-forge xsimdUn paquete para XSIMD está disponible en el Spack Package Manager.
spack install xsimd
spack load xsimdPuede instalarlo directamente desde las fuentes con Cmake:
cmake -D CMAKE_INSTALL_PREFIX=your_install_prefix .
make install Para comenzar a usar xsimd , consulte la documentación completa
http://xsimd.readthedocs.io/
xsimd tiene una dependencia opcional en la biblioteca XTL:
xsimd | xtl (opcional) |
|---|---|
| maestro | ^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 |
Se requiere la dependencia de xtl si desea admitir la vectorización para xtl::xcomplex . En este caso, debe construir su proyecto con soporte C ++ 14 habilitado.
La versión 8 de la biblioteca es una reescritura completa y hay algunas pequeñas diferencias con versiones 7.x. Una guía de migración estará disponible pronto. Mientras tanto, ¿los siguientes ejemplos muestran cómo usar las versiones 7 y 8 de la biblioteca?
Aquí hay un ejemplo que calcula la media de dos conjuntos de 4 valores de punto flotante dobles, suponiendo que sea compatible con la extensión AVX:
# 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 ;
} No olvide habilitar la extensión AVX al construir el ejemplo. Con GCC o Clang, esto se hace con la bandera -mavx , en MSVC debe pasar la opción /arch:AVX .
Este ejemplo sale:
( 2.0 , 3.0 , 4.0 , 5.0 )El mismo cálculo que funciona en vectores y utilizando el conjunto de instrucciones más desempeñados disponibles:
# 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 .;
}
}Construir las pruebas requiere CMake.
cmake está disponible como un paquete para la mayoría de las distribuciones de Linux. Además, también se pueden instalar con el conda Package Manager (incluso en Windows):
conda install -c conda-forge cmake Una vez que se instala cmake , puede construir y ejecutar las pruebas:
mkdir build
cd build
cmake ../ -DBUILD_TESTS=ON
make xtest En el contexto de la integración continua con Travis CI, las pruebas se ejecutan en un entorno conda , que se puede activar con
cd test
conda env create -f ./test-environment.yml
source activate test-xsimd
cd ..
cmake . -DBUILD_TESTS=ON
make xtestLa documentación de XSIMD está construida con tres herramientas
Si bien Doxygen debe instalarse por separado, puede instalar respiración escribiendo
pip install breathe La respiración también se puede instalar con conda
conda install -c conda-forge breatheFinalmente, crea la documentación con
make html Del subdirectorio docs .
Utilizamos un modelo de derechos de autor compartido que permita a todos los contribuyentes mantener los derechos de autor de sus contribuciones.
Este software tiene licencia bajo la licencia de cláusula BSD-3. Consulte el archivo de licencia para obtener más detalles.