sinus / cosinus
-
Gut, passt vieleicht bisschen schlecht ins C++ Forum, is aber inline Assembler.
1. Ich suche den Inline Assembler Quellcode einer cos, sin, tan Funktion(nach möglichkeit x86)
2. Ist die Prozessorklasse wichtig?

Die hier habe ich mal im Internet gefunden:
inline const float sqrt(const float& value) { float result; _asm { mov eax, value sub eax, 0x3f800000 sar eax, 1 add eax, 0x3f800000 mov result, eax } return(result); }--> ist auch einiges schneller, als die sqrt aus <cmath>
3. Weiß jemand, warum?
4. Kann man die Funktion noch optimieren?
-
Tc++H schrieb:
Gut, passt vieleicht bisschen schlecht ins C++ Forum, is aber inline Assembler.
und wozu ist wohl das assemblerforum da?
1. Ich suche den Inline Assembler Quellcode einer cos, sin, tan Funktion(nach möglichkeit x86)
2. Ist die Prozessorklasse wichtig?

sie beeinflußt die auswahl, also ja.
Die hier habe ich mal im Internet gefunden:
--> ist auch einiges schneller, als die sqrt aus <cmath>
3. Weiß jemand, warum?weil sie nicht die wurzel berechnet.
4. Kann man die Funktion noch optimieren?

schon möglich. was willst du denn daran optimieren?
-
camper schrieb:
Tc++H schrieb:
Gut, passt vieleicht bisschen schlecht ins C++ Forum, is aber inline Assembler.
und wozu ist wohl das assemblerforum da?
Hey, komm schon... Er benutzt doch nichtmal 'nen Lötkolben...

Tc++H schrieb:
1. Ich suche den Inline Assembler Quellcode einer cos, sin, tan Funktion(nach möglichkeit x86)
Ich find x86 für diese Aufgabe etwas... naja, wie soll ich's sagen... deplaziert
Tc++H schrieb:
Die hier habe ich mal im Internet gefunden:
inline const float sqrt(const float& value) { float result; _asm { mov eax, value sub eax, 0x3f800000 sar eax, 1 add eax, 0x3f800000 mov result, eax } return(result); }--> ist auch einiges schneller, als die sqrt aus <cmath>
3. Weiß jemand, warum?
*lol*
Tc++H schrieb:
4. Kann man die Funktion noch optimieren?

Ne, die Funktion nicht

Ich würd ja den 80x87 (AKA Math Coprocessor) vorschlagen:
#include <iostream> using namespace std; double sine( double x ) { __asm { FNINIT ; Coprozessor initialisieren FLD x ; x nach ST( 0 ) FSIN ; sinus davon } } // ST( 0 ) - Ergebnis von FSIN - wird zurückgegeben int main( ) { double x = 0.9; cout << "sin( " << x << " ) = " << sine( x ) << endl; }Greetz, Swordfish
PS: Und, was sagt ihr zu meinem allerersten Assemblerprogramm für den 80x87?

-
Hab' grad mal 'ne Laufzeitmessung gemacht. Erschreckend:
#include <iostream> #include <cmath> #include <cstdlib> #include <ctime> #include <windows.h> using namespace std; __forceinline double sine( double x ) { __asm { FNINIT FLD x FSIN } } int main( ) { srand( static_cast< unsigned int >( time( 0 ) ) ); double x[ 1000 ]; for( register unsigned int i = 0; i < 1000; ++i ) { x[ i ] = ( 10000.0 * rand( ) / static_cast< float >( RAND_MAX ) ) / ( 10000.0 * rand( ) / static_cast< float >( RAND_MAX ) ); } __int64 pc_freq, start, stop; QueryPerformanceFrequency( reinterpret_cast< LARGE_INTEGER* >( &pc_freq ) ); QueryPerformanceCounter( reinterpret_cast< LARGE_INTEGER* >( &start ) ); for( register unsigned int i = 0; i < 1000; ++i ) sine( x[ i ] ); QueryPerformanceCounter( reinterpret_cast< LARGE_INTEGER* >( &stop ) ); double total_time = ( static_cast< double >( stop - start ) / pc_freq ) * 1000.0; cout << "Total time elapsed ( 1000 calls to sine( ) ): " << fixed << total_time << " ms" << endl; cout << "Average time elapsed per call: " << fixed << total_time << " us" << endl << endl; QueryPerformanceCounter( reinterpret_cast< LARGE_INTEGER* >( &start ) ); for( register unsigned int i = 0; i < 1000; ++i ) sin( x[ i ] ); QueryPerformanceCounter( reinterpret_cast< LARGE_INTEGER* >( &stop ) ); total_time = ( static_cast< double >( stop - start ) / pc_freq ) * 1000.0; cout << "Total time elapsed ( 1000 calls to sin( ) ): " << fixed << total_time << " ms" << endl; cout << "Average time elapsed per call: " << fixed << total_time << " us" << endl << endl; }Befehlszeile:
/O2 /Og /Ob2 /Oi /Ot /Oy /GL /G5 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /FD /EHsc /ML /GS /Fo"Release/" /Fd"Release/vc70.pdb" /W4 /WX /nologo /c /Wp64 /Gd /TPOutput:
Total time elapsed ( 1000 calls to sine( ) ): 0.166502 ms Average time elapsed per call: 0.166502 us Total time elapsed ( 1000 calls to sin( ) ): 0.002514 ms Average time elapsed per call: 0.002514 usDa sollte wohl doch eher SSE, SSE2, 3DNOW etc. dran

Greetz, Swordfish
-
Swordfish schrieb:
PS: Und, was sagt ihr zu meinem allerersten Assemblerprogramm für den 80x87?

sehr hübsch.

Swordfish schrieb:
Hab' grad mal 'ne Laufzeitmessung gemacht. Erschreckend:
assembler ist zwar low-level aber deswegen nicht unbedingt einfach.

-
Meinst du, man könnte die CRT mit SSE und Kohorten überflügeln?
Greetz, Swordfish
-
nein. gib dem compiler die richtigen switches und der benutzt sowieso intrinsics. schon der versuch dieser microoptimierung von primitiven muss fehlschlagen.