Warum unsigned langsamer als signed?



  • Ich hatte es im Ausgangspost ohne Optimierung getestet, aber habs jetzt nochmal mit -03 und -march=native gemacht (ebenfalls i7 und gcc 4.6.1). Ich komme auch auf die Zeiten von volkard (270 vs. 312 für signed). Auch wenn ich die Schleife länger laufen lasse, bleibt signed bei mir schneller (2920 vs. 3120)

    Mit dem Assemblercode kenne ich mich leider nicht wirklich aus... ich hatte mich bei einem größeren Projekt nur gewundert, dass mein Code mit unsigned langsamer läuft und wollte das deswegen etwas genauer angucken mit dem kleinen Beispiel. Und zumindest auf meinem Rechner hat sich das ja bestätigt.



  • Leider kann man es nicht verallgemeinern. Bei mir ist meistens unsigned ein wenig schneller.

    Vielleicht gibt es bei signed einen Schaltkreis mehr, der vorher einen Größenvergleich macht und als Nebenprodukt eine schnelle Nullnummer machen kann, falls der Zähler kleiner als der Nenner ist. Das habe ich mal weggemacht.

    #include <iostream>
    #include <ctime>
    using namespace std;
    
    int main()
    {
        cout<<"test\n";
        double time1,time2;
        signed int i,a,b,c;
        c=0;
        a=2;
        b=5;
    
        time1 = clock();
        for(i=1;i<90000000;++i)
            c+=(b*i)/(a*i);//andersrum als vorher, und += gegen Wegoptimierung
        time2 = clock();
    
        cout << c << ", " << ((double)(time2-time1)/CLOCKS_PER_SEC)*1000 << endl;
        return 0;
    }
    

    unsigned: 373
    signed: 373


  • Mod

    @volkard: Das ist ja mal lustig:

    signed:

    real 0.339	user 0.340	sys 0.000	pcpu 100.22
    real 0.339	user 0.340	sys 0.000	pcpu 100.27
    real 0.339	user 0.340	sys 0.000	pcpu 100.28
    real 0.339	user 0.340	sys 0.000	pcpu 100.29
    real 0.339	user 0.340	sys 0.000	pcpu 100.29
    real 0.339	user 0.340	sys 0.000	pcpu 100.30
    real 0.339	user 0.340	sys 0.000	pcpu 100.31
    real 0.339	user 0.340	sys 0.000	pcpu 100.31
    real 0.339	user 0.340	sys 0.000	pcpu 100.31
    real 0.339	user 0.340	sys 0.000	pcpu 100.32
    

    unsigned:

    real 0.339	user 0.320	sys 0.020	pcpu 100.29
    real 0.339	user 0.330	sys 0.010	pcpu 100.28
    real 0.339	user 0.330	sys 0.010	pcpu 100.33
    real 0.339	user 0.340	sys 0.000	pcpu 100.15
    real 0.339	user 0.340	sys 0.000	pcpu 100.16
    real 0.339	user 0.340	sys 0.000	pcpu 100.17
    real 0.339	user 0.340	sys 0.000	pcpu 100.17
    real 0.339	user 0.340	sys 0.000	pcpu 100.20
    real 0.339	user 0.340	sys 0.000	pcpu 100.21
    real 0.339	user 0.340	sys 0.000	pcpu 100.22
    

    Den Assembleroutput haben wir ja schon verlgichen, die Compilerversion kann's nicht sein. Das Programm ist gewiss auch nicht durch die externen Komponenten gebremst, das sollte reine CPU sein. Hat vielleicht Intel da ganz was grundlegendes an seiner Architektur geändert? Ich habe hier einen i7-920, also ein Nehalem. Da deiner ein bisschen schneller ist und ich weiß, dass du dir vor ein paar Monaten einen neuen Rechner gekauft hast, nehme ich mal an, du hast eine der neueren Mikroarchitekturen?



  • Glauben manche Leute eigentlich, dass ihr Code so perfekt ist, dass sie auf sowas achten müssen? Oder ist euch nur langweilig?



  • geegtgeegt schrieb:

    Glauben manche Leute eigentlich, dass ihr Code so perfekt ist, dass sie auf sowas achten müssen? Oder ist euch nur langweilig?

    Interesse und auch Langeweile, ja ;)... natürlich sind das alles keine Größenordnungen, aber interessieren tuts mich schon.



  • SeppJ schrieb:

    Ich habe hier einen i7-920, also ein Nehalem. Da deiner ein bisschen schneller ist und ich weiß, dass du dir vor ein paar Monaten einen neuen Rechner gekauft hast, nehme ich mal an, du hast eine der neueren Mikroarchitekturen?

    Ja, "Sandy Bridge" hat mich erst überzeugt.
    http://geizhals.at/deutschland/580311



  • Ich habe aus Interesse den Code auch mal kompiliert mit (i<100000000) in einer Windows 7 VM und eine Feststellung gemacht. Das Resultat mit optimierten Solution Settings: Mit int 375, unsigned int 450!

    Und dann habe ich folgendes gemacht: Visual C++ mit x64 Target und maximalen Optimierungen. Resultat: Beides 125. Kann es sein, dass der Compiler für x86 nicht mehr gut optimiert? Oder dass die neuen CPUs nicht mehr so toll mit den normalen ints umgehen?

    CPU: Sandy Bridge i7 QM, 2.2 GHz.



  • /rant/ schrieb:

    Oder dass die neuen CPUs nicht mehr so toll mit den normalen ints umgehen?

    Nette Idee. Habe mit (un)signed long long gemessen.
    unsigned long long: 0.750s
    signed long long: 0.784s

    Jetzt ist die Welt wieder in Ordnung. :xmas2: :xmas1:


  • Mod

    mit einem Atom N330 bekomme ich diese Wert (unter 64-bit-Gentoo):
    unsigned: 3000 ms
    signed: 3740 ms
    unsigned long long: 7360 ms
    signed long long: 8730 ms




Anmelden zum Antworten