Tenemos un solucionador de CFD y al ejecutar una simulación, se encontró que funcionaba extraordinariamente lento en algunas máquinas pero no en otras. Uso de Intel VTune, se encontró la siguiente línea era el problema (en Fortran):Sustitución de la función powrd extraordinariamente lenta()
RHOV= RHO_INF*((1.0_wp - COEFF*EXP(F0)))**(1.0_wp/(GAMM - 1.0_wp))
de perforación en con VTune, el problema se remonta a la línea call pow
montaje y al trazar la pila, se mostró que estaba utilizando __slowpow()
. Después de buscar, this page apareció quejándose de lo mismo.
En la máquina con la versión 2.12 de libc, la simulación tomó 18 segundos. En la máquina con la versión 2.14 de libc, la simulación tomó 0 segundos.
Según la información en la página mencionada, el problema surge cuando la base para pow()
es cercana a 1.0. Así que hicimos otra prueba simple donde escalamos la base por un número arbitrario antes del pow()
y luego dividimos por el número elevado al exponente después de la llamada pow()
. Esto redujo el tiempo de ejecución de 18 segundos a 0 segundos con el libc 2.12 también.
Sin embargo, no es práctico poner esto sobre el código donde hacemos a**b
. ¿Cómo se podría reemplazar la función pow()
en libc? Por ejemplo, me gustaría que la línea de montaje call pow
generada por el compilador Fortran llame a una función personalizada pow()
que escribamos que hace la escala, llama a la libc pow()
y luego se divide por la escala. ¿Cómo se puede crear una capa intermedia transparente para el compilador?
Editar
Para aclarar, estamos buscando algo como (pseudo-código):
double pow(a,b) {
a *= 5.0
tmp = pow_from_libc(a,b)
return tmp/pow_from_libc(5.0, b)
}
¿Es posible cargar el pow
de libc y cambie su nombre en nuestra función personalizada para evitar los conflictos de nombres? Si el archivo customPow.o
puede renombrar pow
desde libc, ¿qué ocurre si todavía se necesita libc para otras cosas? ¿Eso causaría un conflicto de nombres entre pow
en customPow.o
y pow
en libc?
¡Buen ol 'Fortran! Interesante pregunta +1 –