c++ optimization sse simd intrinsics

Error de C++: ''_mm_sin_ps'' no se declaró en este ámbito



optimization sse (3)

Estoy tratando de comparar diferentes formas de aplicar una función a una matriz.

¿Por qué es https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3260,2124,4779,4779&cats=Trigonometry&text=_sin

_mm_sin_ps no es conocido por mi alcance pero _mm_sqrt_ps ?

¿Cómo lo hago saber? Y compilarlo sin errores.

#include <random> #include <iostream> #include <cmath> #include <chrono> #include <algorithm> #include <valarray> #include "immintrin.h" #include <array> int main() { std::cout<<"start/n"; std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dis(-1000, 1000); int N=100; while(N--) { std::cout<<"/nN: "<<N; const int T1=4E6; { int T=T1,T0=T1/4; std::array<float,T1> array; while(T--) { array[T]=dis(gen); } auto start_time = std::chrono::high_resolution_clock::now(); auto it =array.begin(); while(T0--) { __m128 X = _mm_loadu_ps(it); __m128 result = _mm_sin_ps(X); _mm_storeu_ps(it, result); it+=4; } auto time2=std::chrono::high_resolution_clock::now()-start_time; std::cout<<"/nintr1: "<<std::chrono::duration_cast<std::chrono::microseconds>(time2).count(); } } std::cout<<"/nfin/n"; return 0; }

compilador

g ++ -v

Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion=''Ubuntu 4.8.2-19ubuntu1'' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable- plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)


Como ya se ha señalado, está intentando utilizar la biblioteca SVML de Intel.

Sin embargo, hay varias funciones trascendentales SIMD en la biblioteca sse_mathfun código abierto. La versión original, que usa solo SSE2 está aquí: http://gruntthepeon.free.fr/ssemath/ pero hay una versión más actualizada aquí que se ha actualizado para SSE3 / SSE4 aquí: https://github.com/RJVB/sse_mathfun

La función que desea se llama sin_ps :

v4sf sin_ps(v4sf x);

donde v4sf es solo un typedef para __m128 .

El sse_mathfun original también tiene cos_ps , log_ps y exp_ps , y la versión más nueva (RJVB) tiene algunas funciones adicionales para precisión simple y doble.

He utilizado con éxito ambas versiones de esta biblioteca con gcc, clang e Intel''s ICC (con algunas modificaciones menores para esta última).


__mm_sin_ps es una función intrínseca para llamar a la biblioteca SVML (ya mencionada).

En GCC, SVML está disponible como parte de libmvec en glibc.

Las funciones se nombran de acuerdo con Vector ABI, descrito en el enlace anterior. Las funciones sin, cos, exp, sincos, log, pow están disponibles. Aquí hay un ejemplo para __m128:

#include <x86intrin.h> #include <stdio.h> typedef union { __m128 x; float a[4]; } union128; __m128 _ZGVbN4v_sinf_sse4(__m128); void main() { union128 s1, res; s1.x = _mm_set_ps (0, 0.523599, 1.0472 , 1.5708); res.x =_ZGVbN4v_sinf_sse4(s1.x); fprintf(stderr, "%f %f %f %f/n", res.a[0], res.a[1], res.a[2], res.a[3]); }

¿Hay alguna razón, por qué intrínseco es mejor que usar la función SVML directamente?


_mm_sin_ps es parte de la biblioteca SVML , que se entrega solo con compiladores de inteligencia. Los desarrolladores de GCC se centraron en las instrucciones de la máquina de envoltura y las tareas simples, por lo que no hay SVML en immintrin.h hasta ahora.

Tienes que usar una biblioteca o escribirla tú mismo. Implementación sinusal: