Abbiamo un risolutore CFD e durante l'esecuzione di una simulazione, è stato rilevato che si eseguiva straordinariamente lento su alcune macchine ma non su altre. Utilizzando Intel VTune, è stato trovato il seguente linea era il problema (in Fortran):Sostituzione della funzione Pow() straordinariamente lenta
RHOV= RHO_INF*((1.0_wp - COEFF*EXP(F0)))**(1.0_wp/(GAMM - 1.0_wp))
perforazione con VTune, il problema è stato rintracciato alla linea call pow
montaggio e quando si traccia la pila, mostrava stava usando __slowpow()
. Dopo alcune ricerche, il numero this page si è lamentato della stessa cosa.
Sulla macchina con libc versione 2.12, la simulazione ha impiegato 18 secondi. Sulla macchina con versione di libc 2.14, la simulazione ha richiesto 0 secondi.
In base alle informazioni sulla pagina di cui sopra, il problema sorge quando la base a pow()
è vicina a 1.0. Quindi abbiamo fatto un altro semplice test in cui abbiamo ridimensionato la base con un numero arbitrario prima del pow()
e poi diviso per il numero generato dall'esponente dopo la chiamata pow()
. Questo ha fatto decadere il tempo di esecuzione da 18 secondi a 0 secondi con la libc 2.12.
Tuttavia, non è pratico inserire tutto questo nel codice in cui facciamo a**b
. Come si può sostituire la funzione pow()
in libc? Per esempio, vorrei che la linea di assemblaggio call pow
generata dal compilatore Fortran richiamasse una funzione personalizzata pow()
che scriviamo che esegue il ridimensionamento, chiama la libc pow()
e quindi divide per il ridimensionamento. Come si crea uno strato intermedio trasparente al compilatore?
Modifica
per chiarire, stiamo cercando qualcosa di simile (pseudo-codice):
double pow(a,b) {
a *= 5.0
tmp = pow_from_libc(a,b)
return tmp/pow_from_libc(5.0, b)
}
E 'possibile caricare il pow
da libc e rinominarlo nella nostra funzione personalizzata evitare i conflitti di denominazione? Se il file customPow.o
può rinominare pow
da libc, cosa succede se libc è ancora necessario per altre cose? Ciò causerebbe un conflitto di denominazione tra pow
in customPow.o
e pow
in libc?
Buon vecchio Fortran! Interessante domanda però +1 –