Purtroppo hai scelto un cattivo esempio. Il compilatore JIT x86 non ha metodi inline che restituiscono float. Non sono sicuro al 100% perché, penso di evitare problemi consistenti quando il float viene convertito in un valore in virgola mobile a 80-bit nella FPU. La precisione interna è di 80 bit, ma quei bit aggiuntivi vengono eliminati quando il valore di 80 bit viene troncato su un valore a 32 bit quando viene risucchiato in memoria. Mantenere troppo a lungo il valore nella FPU impedisce che questo troncamento si verifichi e cambia il risultato del calcolo.
se si sostituisce float con un doppio e compilare il codice:
static void Main(string[] args) {
Console.WriteLine(Cube(2.0));
}
Poi viene generato il codice macchina quando l'ottimizzatore JIT è abilitato:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 call 6DA2BEF0 ; Console.get_Out()
00000008 fld qword ptr ds:[010914B0h] ; ST0 = 8.0
0000000e sub esp,8 ; setup argument for WriteLine
00000011 fstp qword ptr [esp]
00000014 mov ecx,eax ; call Console.Out.WriteLine
00000016 mov eax,dword ptr [ecx]
00000018 call dword ptr [eax+000000D0h]
0000001e pop ebp ; done
0000001f ret
Non solo inline le funzioni, è stato in grado di valutare le espressioni al momento della compilazione. E passa direttamente il risultato chiamando Console.WriteLine (8.0). Abbastanza bene eh?
Utilizzare doppio, non galleggiante.
fonte
2010-07-31 15:12:24
Interessante ... perché sto lavorando in XNA dove * tutto * è un float! Leggermente preoccupante ... –
* "Il compilatore JIT x86 non ha metodi inline che restituiscono float." * - Ne sei assolutamente sicuro? Ho cercato in alto e in basso e non riesco a trovare riferimenti per eseguire il backup. Il meglio che ho trovato è stata questa pagina su Connect: https://connect.microsoft.com/VisualStudio/feedback/details/536781/unexpected-jit-inlining-behavior che sembra implicare che le funzioni restituiscono float * do *, infatti, in linea. E questo (vecchio) articolo implica che le regole di coercizione (quindi forse diverse nella pratica) sono le stesse per i float e i doppi: http://blogs.msdn.com/b/davidnotario/archive/2005/08/08/449092. aspx –
@Andrew: le regole di allineamento non sono documentate, solo suggerite in alcuni post del blog. Importante, perché devono essere in grado di modificarlo per migliorare il jitter senza interrompere le ipotesi formulate dal comportamento documentato. Posso solo documentare quello che vedo fare il jitter x86. E sicuramente non incorpora la versione flottante di questi metodi. Vedi un comportamento diverso? –