Optimierung: Was macht der Compiler hier?



  • Beim GCC kann man dem Inline-Assembler mitteilen, in welchen Registern Variablen und Returnwert angenommen werden sollen, genauso bei Open Watcom.
    Der eigentliche Code wird aber auch da nicht angefasst, sonst koennte man es ja auch gleich als C/C++ formulieren.



  • Das hab ich fast angenommen, dass da der Assemblercode Vorrang hat gegenüber der Register-Anweisung.
    Auf das Laden der Variable kommt es auch nicht wirklich an, aber wie würde das gehen den Rückgabewert von atoi direkt im eax zu haben? 😕

    Die ganze Berechnung in asm hätte in C auch nicht viel ausgemacht, aber vielleicht ist's etwas schneller falls C++ den Coprozessor verwenden würde. Wäre auch noch interessant ob der Compiler den Code auf den Wertebereich und Fliesskommazahlen prüft und dann je nach dem die CPU oder FPU benützt.



  • vielleicht ist's etwas schneller falls C++ den Coprozessor verwenden würde

    FPU fuer atoi ?

    wie würde das gehen den Rückgabewert von atoi direkt im eax zu haben

    Integer-Returnwerte werden immer in eax angenommen:

    int res;
       atoi("-12345");
       _asm {
          mov res,eax
       }
       printf("%d \n", res);
    

    Aber nach dem Aufruf einer Funktion (teuer) und dem Parsen eines Strings (noch teurer) kannst Du mit so'm Integer eigentlich nicht mehr viel anstellen dass irgendwie performancerelevant waere...
    Was hast Du denn ueberhaupt vor?



  • Nein nicht für atoi die FPU sondern die Berechnung (Umrechnung von Sekunden) die danach kommt, welche ich in Assembler geschrieben habe. Und ob dafür die FPU genommen würde, das wäre sicherlich langsamer mit allem drum und dran (die Methode wird 2 Mal in der Sekunde ausgeführt).

    Es kommt eigentlich nicht so drauf an, 2 Mal in der Sekunde ist ja nicht soo viel aber ich dachte ich schreibe das mal in Assembler, so einfach wie möglich schadet sicher nicht 🙂
    Ah ja klar wie Windows-Funktionen ebenfalls unter Assembler den Wert in EAX zurückgeben.



  • die "register" anweisung wird übrigens inzwischen von so gut wie allen vompilern komplett ignoriert - ob mit inline-asm oder ohne.



  • Ach so, hoffentlich wird bei einer Schleife im Stil von (int i=0; i==...usw...) wenigstens die Zählvariable gleich im Register angelegt 🙂



  • wenn der compiler dies für sinnvolll hält, schon. also wenns nich noch zig verschachtelte for's sind, dann wird er das machen bei eingeschalteter optimierung.



  • Ah super, immerhin 🙂



  • hellihjb schrieb:

    Der eigentliche Code wird aber auch da nicht angefasst, sonst koennte man es ja auch gleich als C/C++ formulieren.

    nein, c++ hat kein ror/rol/lsb/...



  • nein, c++ hat kein ror/rol/lsb/...

    Man muss es nur etwas komplizierter formulieren:

    unsigned int ror(unsigned int a, unsigned char bits)
    {
       return (a>>bits)|(a<<(32-bits));
    }
    
    // testloop damit der compiler ueberhaupt code erzeugt und keine konstante hinschreibt:
    for (int i=0;i<10;i++)
    {
       unsigned int x= ror(0x12345678, i);
       printf("%d \n ", x);
    }
    

    Disassembly:

    00401010  movzx       ecx,bl 
    00401013  mov         eax,12345678h 
    00401018  ror         eax,cl  ; qed
    0040101A  push        eax
    0040101B  push        offset string "%d \n" (4020E4h) 
    0040101E  call        esi  ; printf
    


  • Welche Kompiler können das?@ror



  • In diesem Fall war's der C++ Compiler von Visual-Studio 2005, andere werden aber aehnlichen Code produzieren.
    Der Befehlssatz der Zielplattform ist dem Compiler ja bekannt und er sollte feststellen koennen, dass das Ergebnis aequivalent mit dem des ror Befehls ist.



  • dafuer gibt es auch entsprechend instrinsics beim VC++: _rotr.
    bei meinem letzten test hatte der gcc das leider nicht auf anhieb erkannt, dass shl shr or zum ror wird, erst als ich "bits" mit &=31 verknuefte.


Anmelden zum Antworten