libreria - math h in c++
¿Por qué es tan ineficiente la biblioteca matemática de gcc? (1)
La mayor parte de esto se debe a las diferencias en la biblioteca de matemáticas. Algunos puntos a considerar:
- Sí, los procesadores x86 con la unidad x87 tienen instrucciones fsin y fcos. Sin embargo, se implementan en microcódigo, y no hay ninguna razón particular por la que deban ser más rápidas que una implementación de software puro.
- GCC no tiene su propia biblioteca matemática, sino que utiliza el sistema proporcionado. En Linux, esto suele ser proporcionado por glibc.
- El glibc x86 de 32 bits usa fsin / fcos.
- x86_64 glibc usa implementaciones de software usando la unidad SSE2. Durante mucho tiempo, fue mucho más lento que la versión glibc de 32 bits que solo usaba las instrucciones x87. Sin embargo, se han realizado mejoras (algo recientes), por lo que, dependiendo de la versión de glibc que tenga, la situación podría no ser tan mala como solía ser.
- El conjunto de compiladores de Intel está bendecido con una biblioteca de matemáticas MUY rápida (libimf). Además, incluye funciones matemáticas trascendentales vectorizadas, que a menudo pueden acelerar aún más los bucles con estas funciones.
Cuando estaba transfiriendo algún código fortran a c, me sorprendió que la mayor discrepancia de tiempo de ejecución entre el programa fortran compilado con ifort (compilador intel fortran) y el programa c compilado con gcc, provenga de las evaluaciones de las funciones trigonométricas ( sin
, cos
). Me sorprendió porque solía creer lo que explica esta answer , que las funciones como seno y coseno se implementan en microcódigo dentro de microprocesadores.
Con el fin de detectar el problema más explícitamente, hice un pequeño programa de prueba en Fortran.
program ftest
implicit none
real(8) :: x
integer :: i
x = 0d0
do i = 1, 10000000
x = cos (2d0 * x)
end do
write (*,*) x
end program ftest
En el procesador intel Q6600
y 3.6.9-1-ARCH x86_64 Linux
ifort version 12.1.0
$ ifort -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.280s
user 0m0.273s
sys 0m0.003s
mientras que con la gcc version 4.7.2
me sale
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.148s
user 0m2.090s
sys 0m0.003s
¡Esto es casi un factor de diferencia de 10! ¿Todavía puedo creer que la implementación gcc de cos
es un envoltorio alrededor de la implementación del microprocesador de una manera similar a como se hace probablemente en la implementación de inteligencia? Si esto es cierto, ¿dónde está el cuello de la botella?
EDITAR
Según los comentarios, las optimizaciones habilitadas deberían mejorar el rendimiento. Mi opinión fue que las optimizaciones no afectan las funciones de la biblioteca ... lo que no significa que no las use en programas no triviales. Sin embargo, aquí hay dos puntos de referencia adicionales (ahora en mi computadora, intel core2
)
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.993s
user 0m2.986s
sys 0m0.000s
y
$ gfortran -Ofast -march=native -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.967s
user 0m2.960s
sys 0m0.003s
¿Qué optimizaciones particulares tenías en mente (comentaristas)? ¿Y cómo puede el compilador explotar un procesador multinúcleo en este ejemplo particular, donde cada iteración depende del resultado del anterior?
Editar 2
Las pruebas de referencia de Daniel Fisher e Ilmari Karonen me hicieron pensar que el problema podría estar relacionado con la versión particular de gcc (4.7.2) y tal vez con una versión específica (Arch x86_64 Linux) que estoy usando en mis computadoras. Así que repetí la prueba en el intel core i7
Box con debian x86_64 Linux
, gcc version 4.4.5
e ifort version 12.1.0
$ gfortran -O3 -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m0.272s
user 0m0.268s
sys 0m0.004s
y
$ ifort -O3 -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.178s
user 0m0.176s
sys 0m0.004s
Para mí, esta es una diferencia de rendimiento muy aceptable, que nunca me haría hacer esta pregunta. Parece que tendré que preguntar en los foros de Arch Linux sobre este tema.
Sin embargo, la explicación de toda la historia es muy bienvenida.