Stavo esaminando un codice che utilizza le flag /fp:precise
e /fp:fast
.Strange/fp Comportamento flag modello floating point
Secondo la MSDN documentation per /fp:precise
:
Con/fp: precise su processori x86, il compilatore eseguirà arrotondamento su variabili di tipo float alla corretta precisione per le assegnazioni e calchi e quando passa parametri a un funzione. Questo arrotondamento garantisce che i dati non mantengano alcun significato superiore alla capacità del suo tipo. Un programma compilato con/fp: preciso può essere più lento e più grande di uno compilato senza/fp: preciso./fp: preciso disabilita gli intrinseci; vengono invece utilizzate le routine di libreria di runtime standard. Per ulteriori informazioni, vedere/Oi (Genera funzioni intrinseche).
Guardando lo smontaggio di una chiamata a sqrtf
(chiamato con /arch:SSE2
, bersaglio x86/Win32
piattaforma):
0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
Da this question credo moderni processori x86/x64 non utilizzano registri 80-bit (o almeno scoraggiare il loro uso), quindi il compilatore fa quello che suppongo sia la cosa migliore e fare calcoli con i doppi a 64 bit. E poiché gli elementi intrinseci sono disabilitati, c'è una chiamata alla funzione sqrtf della libreria.
Ok, abbastanza giusto questo sembra essere conforme a ciò che dice la documentazione.
Tuttavia, quando compilo per l'arco x64, accade qualcosa di strano:
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
I calcoli non vengono rilevati con i doppi a 64 bit, e intrinseche vengono utilizzati. Per quello che posso dire, i risultati sono esattamente gli stessi di quando è stato utilizzato il flag /fp:fast
.
Perché c'è una discrepanza tra i due? /fp:precise
non funziona semplicemente con la piattaforma x64?
Ora, come controllo di integrità ho testato lo stesso codice in VS2010 x86 con /fp:precise
e /arch:SSE2
. Sorprendentemente, è stato utilizzato l'intrinseco sqrtpd
!
00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
Cosa sta succedendo qui? Perché VS2010 utilizza intrinsecamente mentre VS2012 chiama una libreria di sistema?
Il test di VS2010 che ha come target la piattaforma x64 ha risultati simili a quelli di VS2012 (/fp:precise
sembra essere ignorato).
Non ho accesso a nessuna versione precedente di VS, quindi non posso eseguire alcun test su queste piattaforme.
Per riferimento sto testando in Windows 7 64-bit con un processore Intel i5-m430.
Questo è davvero strano. So per certo che '/ fp: precise' a volte farà sì che il compilatore promuova gli intermedi con maggiore precisione a discrezione. Ma questo non spiega la pura incongruenza qui. – Mysticial
"Da questa domanda credo che l'arco x86 non abbia registri a 80 bit" Vieni di nuovo? –
Sì, una strana espressione. Aggiornato per chiarire la raccomandazione generale contro il loro uso. – helloworld922