Ein paar Dinge muß ich noch ergänzen:
- Müßte das
Zitat von
SnuffMaster23:
Code:
cout << "(x<e || x>-e): " << (Start.QuadPart / (double)End.QuadPart) << " Sek." << endl;
nicht viel eher so
Code:
cout << "(x<e || x>-e): " << ((End.QuadPart - Start.QuadPart) / (double)Freq.QuadPart) << " Sek." << endl;
lauten?
- Es heißt _asm, nicht asm (das geht nur beim BCC).
- Zudem glaube ich nach einigen Tests nun, daß die Schleife eher ein paar Durchläufe weniger brauchen könnte
- Mit den genannten Änderungen bekomme ich auf meinem Rechner (XP SP2, Athlon XP 2400+) folgende Ergebnisse (im Bereich der Meßschwankungen gerundet):
VC2008, Release Mode:
(x<e || x>-e): 5.013 s
isNull: 20.325 s
BCB6, Release Mode:
(x<e || x>-e): 7.768 s
isNull: 22.384 s
Bei genauerem Hinsehen ist das auch schlüssig, denn unsere Trickserei mit reinterpret_cast wird im Speicher ausgeführt, wohingegen beispielsweise der BCC im ersten Fall den FCHS-Opcode verwendet, um das Vorzeichen des Gleitkommawertes in einem Register zu verändern. Hinzu kommt, daß auf 32-Bit-Systemen das Schreiben von 64-Bit-Werten in den Speicher länger dauert - und das ist bei unserem Trick nur verzichtbar, wenn wir wissen, ob wir mit einem Big- oder Little-Endian-System arbeiten. Außerdem sind weder MSVC noch BCC in der Lage, von der inline-Funktion viel mehr als die CALL-Anweisung wegzuoptimieren.
Für Fälle wie diesen prägte Donald Knuth den Begriff "premature optimization". Er hat Recht: offensichtlich kommen wir hier viel besser weg, wenn wir dem Compiler eindeutig sagen, was wir haben wollen, anstatt vermeintliche Low-Level-Optimierungen einzubauen.
Zitat von
busybyte:
jetzt bin ich aber wirklich raus aus diesem Thread
Das wäre, glaube ich, für alle Beteiligten ganz angenehm.