sqrt unter Linux langsamer ?
-
Hallo zusammen,
habe ein merkwürdiges Problem festgestellt.
Mein Programm testet die Performance von meinem Event-System.Um realistische Ergebnisse zu erhalten, berechne im Callback des Events :
Execute:
for ( 100 ) sqrt(x)Ein Test auf AMD X2 @ 3.0 Ghz liefert nun:
VS2008 WinXP32: 11 Millionen Iterationen
Linux, gcc 4.3.2. 64bit-Build: 5 Millionen Iterationen
Ein Profiler liefert noch ein viel interessanteres Ergebnis :
VS2008: Funktion Execute ( 80% der Zeit )
Linux : Funktion Execute ( 95% der Zeit )
Es wurden jeweils mit maximalen Optimierungen kompiliert.
Ich programmiere schon länger unter Linux&Windows und solche Unterschiede sind mir noch nie aufgefallen.
Mein Fazit in diesem Fall ... die SQRT-Funktion ist im gcc definitiv langsamer, der Code im allgemeinen schneller.
Was meint ihr dazu ?
Danke für seriöse Antworten
-
Wenn du seriöse Antworten willst, musst du seriöse Fragen stellen. Dazu: 1) Poste bitte den echten Quellcode. 2) Falls der nicht signifikant von dem geposteten Schnipsel abweicht, wird das Ergebnis von sqrt von der Compileroptimierung als unnütz erkannt, also wird die ganze Operation weggeschmissen. 3) Du hast gcc und Visual C++ verglichen, nicht die Betriebssysteme. Dazu müsstest du gcc auf Windows als Vergleich heranziehen.
Zur Ursachenforschung müsste man sich mal den generierten Assemblercode ansehen.
-
Das mit dem Code-Weg-Optimieren ist dem Zusammenhang schon passiert und ich habe den Compiler überlistet

Der Code unterscheidet sich definitiv nicht die Stelle ist wie beschreiben, den Assembler-Code habe ich mir bisher nicht angeschaut.
Der gcc unter Win32 ist für die Tonne, weil schlicht zu alt. Müßte dafür auf nem aktuellen Linux nen 5 Jahren alten Compiler installieren.
Der einzige Unterschied besteht noch im 32Bit-Build unter Windows und 64Bit unter Linux.
-
nurf schrieb:
for ( 100 ) sqrt(x)nurf schrieb:
Der Code unterscheidet sich definitiv nicht die Stelle ist wie beschreiben
Den C++-Compiler möchte ich sehen, der den Code so frißt...
nurf schrieb:
Das mit dem Code-Weg-Optimieren ist dem Zusammenhang schon passiert und ich habe den Compiler überlistet
Wie denn?
nurf schrieb:
Der gcc unter Win32 ist für die Tonne, weil schlicht zu alt. Müßte dafür auf nem aktuellen Linux nen 5 Jahren alten Compiler installieren.
Wie bitte? Es gibt auch aktuelle gcc-Versionen für Windows. Und was hat Linux jetzt damit zu tun?
nurf schrieb:
Der einzige Unterschied besteht noch im 32Bit-Build unter Windows und 64Bit unter Linux.
Ich glaube zwar nicht, daß das der wesentliche Unterschied ist, aber ohne den Code genauer anzugucken, ist das nicht wirklich zu sagen.
So oder so, bei deiner Analyse des "Problems" liegt so einiges im Argen...
-
Zur Vollständigkeit :
void Execute(long * iPT) { // Etwas code fehlt long j = (*iPt); for (unsigned int i = 1; i < 100; ++i ) { (*iPt) = (long)(sqrt((double)j)) ; } (*iPt) = j; }[Ironie]Du kennst dich wahrlich gut mit dem GCC-Port und Win32 alias MingW32 aus[/Irone]
-
Sind das jetzt beim gcc 64-Bit-Zeigeroperationen und beim VC++ nur 32 Bit?
-
Bashar schrieb:
Sind das jetzt beim gcc 64-Bit-Zeigeroperationen und beim VC++ nur 32 Bit?
Ja, in diese Richtung habe ich auch schon überlegt.
-
-
Danke .filmor,
werde ich zeitnah mal testen.
Für Theorien bin ich auch weiterhin zu haben.
-
nurf schrieb:
Ja, in diese Richtung habe ich auch schon überlegt.
Und wie wärs mit überprüfen?
-
Bashar schrieb:
Sind das jetzt beim gcc 64-Bit-Zeigeroperationen und beim VC++ nur 32 Bit?
Nicht nur das, sondern auch long hat beim gcc auf x86-64 eine Größe von 64 Bit.
Von daher würde ich nicht nur gcc unter Windows mal ausprobieren, sondern vor allem auch gcc unter einem 32-bittigen Linux (wahrscheinlich reicht auch schon
gcc -m32unter dem 64-Bit Linux).
-
nurf schrieb:
Zur Vollständigkeit :
void Execute(long * iPT) { // Etwas code fehlt long j = (*iPt); for (unsigned int i = 1; i < 100; ++i ) { (*iPt) = (long)(sqrt((double)j)) ; } (*iPt) = j; }[Ironie]Du kennst dich wahrlich gut mit dem GCC-Port und Win32 alias MingW32 aus[/Irone]
- Was ist dir bitte an 4.3 zu alt? Wenn du schon keine Ahnung hast welche GCC Versionen es für Windows gibt, dann bitte keine solchen Sprüche.
- Der Code ist für die Tonne. Mach eine Schleife, summiere die Quadratwurzeln des Schleifenzählers, und gib die Zahl danach aus (printf). Für doofe:
void foo() { double v = 1; double accu = 0; for (size_t i = 0; i < limit; i++) // limit darf nicht konstant sein, sonst könnte der Compiler theoretisch wieder alles wegoptimieren, // also limit als Parameter an die .exe übergeben lassen { v += 1.0; accu += sqrt(v); } printf("%f\n", accu); }- Die FPU Einstellungen bzw. entsprechenden Compiler-Einstellungen werden hier wohl auch reinspielen.
Ich will nicht behaupten dass es keinen Unterschied zwischen Linux und Windows geben kann (kann es, gibt durchaus Dinge die Linux anders machen könnte als Windows, z.B. die Default Einstellungen für die FPU), bloss ist deine Messmethode mindestens fragwürdig.