Ich untersuchte einen Code, der die /fp:precise
- und /fp:fast
-Flags verwendet.Seltsames/fp Gleitkomma-Modellflaggenverhalten
Nach dem MSDN documentation für /fp:precise
:
mit/fp: präzise auf x86-Prozessoren, der Compiler auf Variablen vom Typ float auf die richtige Präzision für Zuweisungen und Abgüsse Abrunden wird zuführen und, wenn Parameter in einer Weitergabe Funktion. Diese Rundung garantiert, dass die Daten keine größere Bedeutung als die Kapazität ihres Typs behalten. Ein mit/fp: precise kompiliertes Programm kann langsamer und größer als eins sein, das ohne/fp: precise kompiliert wurde./fp: präzise deaktiviert intrinsics; Die Routinen der Standardlaufzeitbibliothek werden stattdessen verwendet. Weitere Informationen finden Sie unter/Oi (Intrinsische Funktionen generieren).
Mit Blick auf die Demontage eines Anrufs zu sqrtf
(mit /arch:SSE2
genannt, Ziel x86/Win32
Plattform):
0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
Von this question I modernen x86/x64-Prozessoren glauben nicht 80-Bit-Register verwenden Sie (oder zumindest ihre Verwendung abschrecken), so dass der Compiler das tut, was ich für das nächstbeste halten würde, und Berechnungen mit 64-Bit-Doubles mache. Und weil intrinsics deaktiviert sind, gibt es einen Aufruf an eine Bibliothek sqrtf-Funktion.
Ok, fairerweise scheint dies zu entsprechen, was die Dokumentation sagt.
Allerdings, wenn ich für die x64 Bogen kompilieren, geschieht etwas Seltsames:
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
Die Berechnungen werden nicht mit 64-Bit-Doppel durchgeführt und Spezifika verwendet werden. Soweit ich das beurteilen kann, sind die Ergebnisse genau so, als ob das /fp:fast
Flag verwendet würde.
Warum gibt es eine Diskrepanz zwischen den beiden? Funktioniert /fp:precise
einfach nicht mit der x64-Plattform?
Nun, als eine Überprüfung der Gesundheit getestet habe ich den gleichen Code in VS2010 x86 mit /fp:precise
und /arch:SSE2
getestet. Überraschenderweise wurde die sqrtpd
intrinsische verwendet!
00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
Was ist hier los? Warum verwendet VS2010 Intrinsics, während VS2012 eine Systembibliothek aufruft?
Das Testen von VS2010 mit Ausrichtung auf die x64-Plattform hat ähnliche Ergebnisse wie VS2012 (/fp:precise
scheint ignoriert zu werden).
Ich habe keinen Zugriff auf ältere Versionen von VS, so dass ich keine Tests auf diesen Plattformen durchführen kann.
Als Referenz teste ich in Windows 7 64-Bit mit einem Intel i5-M430-Prozessor.
Das ist wirklich seltsam. Ich weiß aus der Tatsache, dass '/ fp: precise' manchmal dazu führt, dass der Compiler Intermediates mit höherer Präzision diskret unterstützt. Aber das erklärt nicht die schiere Unstimmigkeit hier. – Mysticial
"Von dieser Frage glaube ich, dass der x86-Arch keine 80-Bit-Register hat" Komm schon wieder? –
Ja, seltsame Formulierung. Aktualisiert, um die allgemeine Empfehlung gegen ihre Verwendung zu klären. – helloworld922