2011-02-24 11 views
7

Estoy buscando el cálculo de funciones trigonométricas altamente paralelizadas (en bloque de 1024 como el mismo), y me gustaría aprovechar al menos parte del paralelismo que tienen las arquitecturas modernas.Funciones vectorizadas de Trig en C?

Cuando compilo un bloque

for(int i=0; i<SIZE; i++) { 
    arr[i]=sin((float)i/1024); 
} 

GCC no vectorizar, y dice

not vectorized: relevant stmt not supported: D.3068_39 = __builtin_sinf (D.3069_38); 

que tiene sentido para mí. Sin embargo, me pregunto si hay una biblioteca para hacer cálculos trigonométricos paralelos.

Con solo una simple serie taylor en el orden 11, GCC vectorizará todos los bucles, y obtengo velocidades superiores al doble de un ciclo sin sentido (con respuestas de bits exactos, o con series de orden 9, solo un bit apagado para los dos últimos valores de 1600, para una aceleración> 3x). Estoy seguro de que alguien se ha encontrado con un problema como este antes, pero cuando busco en Google, no encuentro menciones de ninguna biblioteca o similar.

A. ¿Ya existe algo?
B. Si no, ¿consejos para optimizar las funciones trigonométricas paralelas?

EDIT: encontré la siguiente biblioteca llamada "SLEEF": http://shibatch.sourceforge.net/ que se describe en el documento this y usa instrucciones SIMD para calcular varias funciones elementales. Utiliza código específico SSE y AVX, pero no creo que sea difícil convertirlo en bucles C estándar.

Respuesta

1

¿Qué plataforma está utilizando? Ya existen muchas bibliotecas de este tipo:

  • Intel proporciona la Vector Math Library (VML) con icc.
  • Apple proporciona la biblioteca vForce como parte del marco Accelerate.
  • HP proporciona su propia Biblioteca de vectores matemáticos para Itanium (y también para otras arquitecturas).
  • Sun proporcionó libmvec con sus herramientas de compilación.
  • ...
+0

estoy en x86_64 Debian/Linux, GCC. Idealmente, me gustaría algo que funcione en la mayoría de las plataformas para las que GCC es compatible con la vectorización. –

2

Puesto que usted está buscando para el cálculo de armónicos aquí, tengo algunas code that addressed a similar problem. Ya está vectorizado y es más rápido que cualquier otra cosa que haya encontrado. Como beneficio secundario, obtienes el coseno gratis.

+0

Agradable, pero me gustaría algo un poco más portátil que el ensamblaje. –

+0

En ese caso, recomendaría NETLIB. Puede encontrar una buena implementación en la biblioteca framewave de AMD: http://framewave.svn.sourceforge.net/viewvc/framewave/trunk/Framewave/domain/common/include/Trigonometric_NETLIB.h?revision=HEAD&view=markup – Seth

3

ya que dijo que estaba usando GCC parece que hay algunas opciones:

Dicho esto, probablemente me miro en GPGPU de una solución.Tal vez escribirlo en CUDA o OpenCL (si no recuerdo mal, CUDA admite la función seno). Aquí hay algunas bibliotecas que parecen que podrían hacerlo más fácil.

+1

OpenCL proporciona vector sobrecargas para todas las funciones matemáticas. Creo que CUDA también lo hace. –

1

En lugar de la serie de Taylor, me gustaría ver a los algoritmos fdlibm usos. Deben obtener tanta precisión con menos pasos.

+0

fdlibm solo usa una aproximación polinomial: http://www.netlib.org/fdlibm/k_sin.c –

+2

@JeremySalwen ... pero los coeficientes de estos polinomios no están tomados de la serie de Taylor; fueron elegidos utilizando métodos más sutiles: http://en.wikipedia.org/wiki/Minimax_approximation_algorithm. Y si observa k_cos.c, que es más difícil que k_sin.c porque los argumentos más grandes hacen que uno calcule con ULP grandes para un pequeño resultado que se espera sea preciso para una ULP pequeña, notará una técnica de compensación interesante, que hace que la vectorización más complicado. –