Hier ist mein Code:
int f(double x)
{
return isnan(x);
}
Wenn ich #include <cmath>
Ich bekomme diese Baugruppe:
xorl %eax, %eax
ucomisd %xmm0, %xmm0
setp %al
Das ist einigermaßen clever: ucomisd setzt das Parity-Flag, wenn der Vergleich von x mit sich selbst unsortiert ist, also x NAN ist. Dann Einst kopiert das Parity-Flag in das Ergebnis (nur ein einzelnes Byte, daher das anfängliche Löschen von %eax
).
Aber wenn ich #include <math.h>
Ich bekomme diese Baugruppe:
jmp __isnan
Jetzt ist der Code nicht inline, und die __isnan
schneller ist die funktion sicherlich nicht ucomisd
Anweisung, also haben wir einen Sprung ohne Nutzen angefallen. Ich bekomme das gleiche, wenn ich den Code als C kompiliere.
Wenn ich jetzt die ändere isnan()
Aufruf __builtin_isnan()
ich verstehe das einfach ucomisd
Anweisung Anweisung unabhängig davon, welchen Header ich einfüge, und es funktioniert auch in C. Ebenso wenn ich gerade return x != x
.
Meine Frage ist also, warum C <math.h>
Header bieten eine weniger effiziente Implementierung von isnan()
als C++ <cmath>
Header? Wird von den Menschen wirklich erwartet, dass sie verwenden __builtin_isnan()
und wenn ja, warum?
Ich habe GCC 4.7.2 und 4.9.0 auf x86-64 mit getestet -O2
und -O3
Optimierung.
Hier ist meine Spekulation: Vor c99 gibt es keine Inline-Funktion in c. keine Inline-Funktion bedeutet, dass Funktionen von jmp/call (oder einer Art Verzweigung) aufgerufen werden müssen. __builtin_isnan ist nicht Teil von c. es ist wahrscheinlich eine plattformspezifische Eigenart.
– Ding
26. September 2014 um 5:58 Uhr
Aber sicherlich ein Systemheader wie
<math.h>
können plattformspezifische integrierte Funktionen verwenden.– John Kugelmann
26. September 2014 um 6:01 Uhr
Ich bin ziemlich sicher
isnan
würde benutzen__builtin_isnan
wenn möglich. Ich sehe keinen Grund, warum Sie es manuell aufrufen müssten.– Raptz
26. September 2014 um 6:01 Uhr
Als C99 auftauchte, dachte vielleicht niemand daran, zurück zu gehen und isnan zu aktualisieren
– Ding
26. September 2014 um 6:04 Uhr
sourceware.org/bugzilla/show_bug.cgi?id=15367
– Marc Glisse
26. September 2014 um 6:08 Uhr