Nimmt Wurzelziehen viel Performance?



  • Wenn wir grad schon mit dem Assembler Zeug anfangen, weiß jemand wie man die intrinsics für sowas (oder aber sin, pow...) reichtig benutzt. Ist das einfach ein Problem meines Compilers (VC8 Express), das ich trotzdem immer Linkerfehler bekomme wenn ich die Fkt. nicht als Asm Schnippel schreibe, habe ich das Konzept nicht verstanden oder bin ich einfach nur zu dumm dazu? Leider hält das Netz dazu nicht so viele Infos bereit, das ich aus der Sache wirklich schlau geworden wäre.

    Bye, TGGC (Das Eine, welches ist.)



  • Hi!

    Hast du mal ein Beispiel deiner Funktion parat? Dann könnte vllt jemand diese testen und dir bessere Ressonanz zurückgeben. 🙂

    Sinus unter verwendung der FPU, sollte so compiliert werden:

    float FSin( float x )
    {
      __asm 
      {
        fld x
        fsin
      }
    }
    

    grüße


  • Mod

    TGGC schrieb:

    ...bla...

    soviel zum thema

    , putzig.



  • TGGC schrieb:

    ...oder bin ich einfach nur zu dumm dazu?..

    Danke, Gott, dass ich diesen Tag erleben durfte. 😃



  • weiß jemand wie man die intrinsics für sowas richtig benutzt.
    Ist das einfach ein Problem meines Compilers, das ich trotzdem immer Linkerfehler bekomme wenn ich die Fkt. nicht als Asm Schnippel schreibe

    vs2003 setzt die intrinsics fuer math.h bei /O2 von alleine ein.



  • Tja, ich hab schon vieles probiert. Bisher hat er dann immer noch kryptische Symbole wie "__CIsin" gesucht. Das heisst ja dann, das er doch nicht einfach nur das fsin in den Code haut, wie ich mir das vorstell. Genauso hab ich mit 'ner eigene Funktion das Problem, das die Daten doch wieder über Stack oder den Speicher gehen, obwohl sie doch ehh schon bei der FPU sind. Aber wie sagt man noch: "float is bloat". f'`8k

    Bye, TGGC (Das Eine, welches ist.)



  • The floating-point functions listed below have true intrinsic forms when you specify both the /Oi and /Og compiler options:
    atan exp log10 sqrt atan2 log sin tan cos

    You can use the /Op or /Za compiler option to override generation of true intrinsic floating-point options.
    In this case, the functions are generated as library routines that pass arguments directly to the
    floating-point chip instead of pushing them onto the program stack.

    (msdn)

    wenn der compiler deine funktion inlined, faellt der stack-umweg sowieso dem optimizer zum opfer.



  • Dein Link geht auf "Embedded Operating System Development"? Laut VS Doku ist /Og ist deprecated und /Op ist nicht aufgeführt. Und inlinen meiner Funktion bringt mir ja auch nur bedingt was, da der Compiler dann den Context der Funktion trotzdem nicht kennt und so evtl. weniger optimaler Code ensteht (float erst im Speicher abgelegt).

    Ich habe nun aber nach langem probieren rausgefunden, wie ich VC8 Exress überreden kann. Es reicht nicht, das Floating Point Model auf "FAST" zu stellen, wodurch "fp:fast" in der Kommandozeile erscheint, man muss den Switch von Hand zusätzlich eintragen. Entweder wird er sonst durch einen anderen Switch wieder deaktiviert (davon finde ich in der Doku aber nichts), oder das funktioniert nicht, wie es eigentlich soll oder MS wollte es genau so (d.h. es sollte eigentlich nur in der Proffesional funktionieren).

    Und gegenüber der eigenen Funktion (inline) ergibt sich dadurch folgender Vorteil:

    ; 696  : 		return sin( fStep * c_f2Pi );
    
    	fmul	DWORD PTR _c_f2Pi
    	fstp	DWORD PTR $T64355[ebp]
    	fld	DWORD PTR $T64355[ebp]
    	fsin
    	fstp	DWORD PTR $T64355[ebp]
    	fld	DWORD PTR $T64355[ebp]
    
    	leave
    	ret	0
    

    intrinsic:

    ; 696  : 		return sin( fStep * c_f2Pi );
    
    	fmul	DWORD PTR _c_f2Pi
    	fsin
    
    	leave
    	ret	0
    

    Bye, TGGC (Das Eine, welches ist.)



  • Wird Wurzelziehen nicht sehr oft in zB Spielen verwendet?
    Wieso wird dann die Wurzel nicht Hard gemacht, also in Silizium gegossen ?
    Genauso wie Potenzen werden ja auch oft verwendet.



  • Und gegenüber der eigenen Funktion (inline) ergibt sich dadurch folgender Vorteil
    [...]

    und das liegt daran, dass dein eigener "sin" float zurueck liefert und der compiler dabei einen double-float-cast mit hilfe von fstp/fld durchfuehrt.
    mach die parameter double und du kriegst das gleiche compilat wie mit intrinsics.


  • Mod

    DEvent schrieb:

    Wird Wurzelziehen nicht sehr oft in zB Spielen verwendet?
    Wieso wird dann die Wurzel nicht Hard gemacht, also in Silizium gegossen ?
    Genauso wie Potenzen werden ja auch oft verwendet.

    ist beides im silicium der meisten cpus/fpus.



  • rapso schrieb:

    unter c++ heißt die funktion fabs bzw fabsf.

    Wobei es in C++ nur fabs gibt, fabsf ist C.



  • hellihjb schrieb:

    Und gegenüber der eigenen Funktion (inline) ergibt sich dadurch folgender Vorteil
    [...]

    und das liegt daran, dass dein eigener "sin" float zurueck liefert und der compiler dabei einen double-float-cast mit hilfe von fstp/fld durchfuehrt.
    mach die parameter double und du kriegst das gleiche compilat wie mit intrinsics.

    Falsch. Ich arbeite mit floats, siehe oben. Der Compiler optimiert nie in Inline Assembler, darum kann es mit eigenet Funktion nie so funktionieren. Siehe auch oben, das fld steht im asm Block, bleibt daher immer erhalten.

    Bye, TGGC (Das Eine, welches ist.)


Anmelden zum Antworten