performance windows <-> linux
-
Holla,
ich habe mal ein sehr seltsames "Problem" gleicher Code unter Windows und Linux mit dem gcc 4.5.1 compiliert und ausgeführt:
C:\DundE\anh\Eigene Dateien\downloads>cmp_athlon.exe C strcpy: 4821.1 MB/second (2560.0 MB in 531 clocks) our strcpy1: 4196.7 MB/second (2560.0 MB in 610 clocks) our strcpy2: 3148.8 MB/second (2560.0 MB in 813 clocks) C memcpy: 2873.2 MB/second (2560.0 MB in 891 clocks) our memcpy: 1973.8 MB/second (2560.0 MB in 1297 clocks) C:\DundE\anh\Eigene Dateien\downloads>cmp_i686.exe C strcpy: 4812.0 MB/second (2560.0 MB in 532 clocks) our strcpy1: 2976.7 MB/second (2560.0 MB in 860 clocks) our strcpy2: 3091.8 MB/second (2560.0 MB in 828 clocks) C memcpy: 2825.6 MB/second (2560.0 MB in 906 clocks) our memcpy: 1949.7 MB/second (2560.0 MB in 1313 clocks)und linux:
cmp_i686 -------------- C strcpy: 3764.7 MB/second (2560.0 MB in 680000 clocks) our strcpy1: 2976.7 MB/second (2560.0 MB in 860000 clocks) our strcpy2: 3084.3 MB/second (2560.0 MB in 830000 clocks) C memcpy: 3084.3 MB/second (2560.0 MB in 830000 clocks) our memcpy: 1969.2 MB/second (2560.0 MB in 1300000 clocks) cmp_athlon ----------------- C strcpy: 3764.7 MB/second (2560.0 MB in 680000 clocks) our strcpy1: 4000.0 MB/second (2560.0 MB in 640000 clocks) our strcpy2: 3122.0 MB/second (2560.0 MB in 820000 clocks) C memcpy: 3122.0 MB/second (2560.0 MB in 820000 clocks) our memcpy: 1984.5 MB/second (2560.0 MB in 1290000 clocks)wie kommt es, dass Windows schneller Strings kopieren kann? Bzw wieso sind es unter Windows deutlich weniger clocks? Der Compiler sollte eigentlich nichts wegoptimieren ...
mfg
so hier noch, wer den C Code sehen möchte:
/**** * * modified version from Preston L. Bannister * **/ #include <stdlib.h> #include <stdio.h> #include <time.h> #include <string.h> /******************************************************************************* ******************************************************************************* * configs ******************************************************************************* ******************************************************************************/ #define LOOPS 10000000 static const char sOut1[] = "QBTnetfnh8TpTWvPzARBNWr2gMFofe3AzwMXVOGbdL2xOOACwMefrMxpxZ62qakW"; static const char sOut2[] = "ct6V7lZ42RoryDlvM1EzT54T5qV3DGUA4UIIhVv0TSK0lTx0TKIFc4E4YIdfjfKp"; /******************************************************************************* ******************************************************************************* * engine ******************************************************************************* ******************************************************************************/ unsigned int nLength = ::strlen(sOut1); unsigned int dtLoop = 0; unsigned int nTotal = 0; char sWork[256]; typedef void (*doit)(const char*, const char*); void report_times(const char* s, unsigned int dt) { double ts = (double)dt / CLOCKS_PER_SEC; double mb = (double)(nTotal) / 1000000; double rate = mb / ts; printf("%s:\t\t %0.1f MB/second (%0.1f MB in %u clocks)\n", s, rate, mb, dt); } int time_function(doit fn) { clock_t t0 = ::clock(); for (int i=0; i<LOOPS; ++i) { const char* s1 = sOut1 + (15 & i); const char* s2 = sOut2 + nLength - (15 & i); (*fn)(s1,s2); } return (int)(::clock() - t0) - dtLoop; } void do_total(const char* s1,const char* s2) { nTotal += 4 * nLength; } /******************************************************************************* * end engine ******************************************************************************/ /******************************************************************************* ******************************************************************************* * benchmark ******************************************************************************* ******************************************************************************/ void do_c_strcpy(const char* s1,const char* s2) { ::strcpy(sWork,s1); ::strcpy(sWork,s2); } void our_strcpy1(char* s1,const char* s2) { while (*s1++ = *s2++); } void our_strcpy2(char* s1,const char* s2) { register unsigned int i; for (i = 0; s2[i] != 0; ++i) s1[i] = s2[i]; s1[i] = 0; } void do_our_strcpy1(const char* s1,const char* s2) { our_strcpy1(sWork,s1); our_strcpy1(sWork,s2); } void do_our_strcpy2(const char* s1,const char* s2) { our_strcpy2(sWork,s1); our_strcpy2(sWork,s2); } void do_c_memcpy(const char* s1, const char* s2) { int l1 = strlen(s1); int l2 = strlen(s2); ::memcpy(sWork, s1, l1); ::memcpy(sWork, s2, l2); } void our_memcpy(char* dest, const char* src, int size) { for(int i=0; i<size; ++i) dest[i] = src[i]; } void do_our_memcpy(const char* s1, const char* s2) { int l1 = strlen(s1); int l2 = strlen(s2); our_memcpy(sWork, s1, l1); our_memcpy(sWork, s2, l2); } /******************************************************************************* * end benchmark ******************************************************************************/ /******************************************************************************* ******************************************************************************* * main programm ******************************************************************************* ******************************************************************************/ int main(int ac,char** av) { dtLoop = time_function(do_total); report_times("C strcpy", time_function(do_c_strcpy)); report_times("our strcpy1", time_function(do_our_strcpy1)); report_times("our strcpy2", time_function(do_our_strcpy2)); report_times("C memcpy", time_function(do_c_memcpy)); report_times("our memcpy", time_function(do_our_memcpy)); return 0; }
-
ach und noch eben von meinem Laptop:
C:\Users\Lappi\Desktop\xcp>cmp_686.exe C strcpy: 3731.8 MB/second (2560.0 MB in 686 clocks) our strcpy1: 3417.9 MB/second (2560.0 MB in 749 clocks) our strcpy2: 3417.9 MB/second (2560.0 MB in 749 clocks) C memcpy: 2562.6 MB/second (2560.0 MB in 999 clocks) our memcpy: 1823.4 MB/second (2560.0 MB in 1404 clocks) C:\Users\Lappi\Desktop\xcp>cmp_core2.exe C strcpy: 4238.4 MB/second (2560.0 MB in 604 clocks) our strcpy1: 3699.4 MB/second (2560.0 MB in 692 clocks) our strcpy2: 3459.5 MB/second (2560.0 MB in 740 clocks) C memcpy: 2552.3 MB/second (2560.0 MB in 1003 clocks) our memcpy: 2051.3 MB/second (2560.0 MB in 1248 clocks) [dd@lappy Downloads]$ ./cmp_686 C strcpy: 1113.0 MB/second (2560.0 MB in 2300000 clocks) our strcpy1: 1497.1 MB/second (2560.0 MB in 1710000 clocks) our strcpy2: 1523.8 MB/second (2560.0 MB in 1680000 clocks) C memcpy: 1630.6 MB/second (2560.0 MB in 1570000 clocks) our memcpy: 1207.5 MB/second (2560.0 MB in 2120000 clocks) [dd@lappy Downloads]$ ./cmp_core2 C strcpy: 1075.6 MB/second (2560.0 MB in 2380000 clocks) our strcpy1: 1741.5 MB/second (2560.0 MB in 1470000 clocks) our strcpy2: 1706.7 MB/second (2560.0 MB in 1500000 clocks) C memcpy: 1600.0 MB/second (2560.0 MB in 1600000 clocks) our memcpy: 1213.3 MB/second (2560.0 MB in 2110000 clocks)
-
Mit welchen Compiler-Flags hast du unter Linux kompiliert ?
-
Kompilierst du mit einer IDE? Wenn du beispielsweise unter Code::Blocks den Release Mode wählst werden automatisch Optimier-Flags gesetzt..
Also wie mein Vorredner: Wie und auf welche Art kompilierst du? Also welche Flags werden genutzt..
-
ohh sorry, ich dachte ich habe es geschrieben .....
ich habe mit gcc 4.5.1 mit -O2 -s -march=[i685 bzw core2 bzw athlon]
Ich vermute mal, dass Windows die Funktionen in assembler optimiert hat (für amd und intel)
-
linux schon auch... denkst du wirklich wenn linux so langsam wäre wie du es hier schilderst würde es auf servern laufen?
-
was spricht gegen ein -march=native ?
-
Pigeon schrieb:
was spricht gegen ein -march=native ?
native ist bei mir i686, archlinux eben
aber da ich i5 habe ist core2 besser ...
-
anh schrieb:
Pigeon schrieb:
was spricht gegen ein -march=native ?
native ist bei mir i686, archlinux eben
aber da ich i5 habe ist core2 besser ...? Korrigier mich wenn ich mich irre, aber bei native sucht dir gcc anhand der CPU information die optimalen CFLAGS. Bei mir wären as folgende:
Tux>$ cc -march=native -E -v - </dev/null 2>&1 | grep cc1
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.4.3/cc1 -E -quiet -v - -D_FORTIFY_SOURCE=2 -march=core2 -mcx16 -msahf --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=2048 -mtune=core2Habe ein bisschen mit dienem Program herumgespielt und bekomme teilweise nur 1/3 der performance bei anderen flags.
-
Hallo,
Hmm... ich bekomme deinen Code mit dem gcc (4.3.2) überhaupt nicht kompiliert.
Falls ich falsch informiert bin, korrigiert mich bitte, aber die Doppelpunkte um den Namensraum anzugeben (::strlen) gehören nicht zum C-Standard (habe es auch mit -std=c99 und gnu99 versucht, immernoch erfolglos), und wenn die Datei nicht mit *.c endet, sondern mit *.cpp oder ähnlich, nimmt der gcc automatisch den C++-Compiler. Ansonsten liegts wohl an meinem älteren Compiler... Debian eben...Zum Programm:
Habs mit g++ und dem Mingw-Crosscompiler auf beiden Plattformen versucht und komme auf 'ähnliche' Ergebnisse: D.h. die Kopiergschwindigkeiten (MB/s) sind fast identisch (und gefühlt auch gleich performant), aber die Anzahl der Clocks ist unterschiedlich (Faktor 1000). Kompiliert mit 'g++ -s -march=x86-64 -O2 test.cpp -o test'. Habs auch mit -march=native probiert: selbes Ergebnis. Selbst der Grad der Optimierung ist für den deutlichen Unterschied in der Anzahl der Clocks nicht verantwortlich. Selbst ohne Optimierung ist da noch ein Faktor von 1000 zwischen.Frage oben bleibt bestehen: Wie heißt deine Datei?
Mein virtuelles Linux ist in dieser Hinsicht schneller als mein Windows 7 :).. DAS sollte mir zu denken geben...
-
nobody44 schrieb:
Hallo,
Hmm... ich bekomme deinen Code mit dem gcc (4.3.2) überhaupt nicht kompiliert.
Falls ich falsch informiert bin, korrigiert mich bitte, aber die Doppelpunkte um den Namensraum anzugeben (::strlen) gehören nicht zum C-Standard (habe es auch mit -std=c99 und gnu99 versucht, immernoch erfolglos), und wenn die Datei nicht mit *.c endet, sondern mit *.cpp oder ähnlich, nimmt der gcc automatisch den C++-Compiler. Ansonsten liegts wohl an meinem älteren Compiler... Debian eben...Zum Programm:
Habs mit g++ und dem Mingw-Crosscompiler auf beiden Plattformen versucht und komme auf 'ähnliche' Ergebnisse: D.h. die Kopiergschwindigkeiten (MB/s) sind fast identisch (und gefühlt auch gleich performant), aber die Anzahl der Clocks ist unterschiedlich (Faktor 1000). Kompiliert mit 'g++ -s -march=x86-64 -O2 test.cpp -o test'. Habs auch mit -march=native probiert: selbes Ergebnis. Selbst der Grad der Optimierung ist für den deutlichen Unterschied in der Anzahl der Clocks nicht verantwortlich. Selbst ohne Optimierung ist da noch ein Faktor von 1000 zwischen.Frage oben bleibt bestehen: Wie heißt deine Datei?
Mein virtuelles Linux ist in dieser Hinsicht schneller als mein Windows 7 :).. DAS sollte mir zu denken geben...
danke für deine Tests

also der clock unterschied liegt darin, dass linux etwas mehr clocks sendet als windows windows wahrscheinlich nur jede ms oder so und linux ns

die optimierung und march sachen sollten auf c functionen keine auswirkung haben, da diese ja mit glibc bzw msvcrt gelinkt werden, es ging mehr um die "our strcpy" und halt die vorkompilierten stdlib (glibc und msvcrt)
mfg