[C++] Gleitkomma- zu Ganzzahlen runden

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Gleitkomma- zu Ganzzahlen runden

Beitrag von Krishty »

So, kleines Update … ohne frndint hat sich die Performance nochmal fast verdoppelt, ich bin jetzt bei der 45-fachen Geschwindigkeit eines static_cast – danke, Jörg.

Mit dem Assembler-Code, der nun endlich nicht mehr inline-Assembler ist, sondern mit MASM assembliert und extern gelinkt wird, ist allerdings der GAU eingetreten: Er wird nicht geinlined. Die Performance ist damit um den Faktor 100 schlechter geworden und ist nun nurnoch halb so schnell wie ein static_cast.

Hat jemand ein gutes Tutorial darüber, wie man MASM-Kompilate richtig in Visual-C++-Projekte einbindet und optimiert? Ich habe mich da quasi blind reingetastet und ihr seht, was rauskommt …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Gleitkomma- zu Ganzzahlen runden

Beitrag von Krishty »

Ich habe keinen Bock mehr … ich werde erstmal die SSE-Intrinsics nutzen … sind genauso schnell wie fistp aber x86- sowie x64-tauglich … CPUs ohne SSE sind eh zu langsam für meine Bedürfnisse und den winzigen Präzisionsunterschied gegenüber der FPU würde ich ja eh nicht messen können … Assembler ist nervtötend und wenn ich noch mehr Zeit auf das Thema verschwende, kriege ich garnichts mehr gebacken -.-

Daher meine vorläufige Lösung, falls ihr nichts daran auszusetzen habt:

Code: Alles auswählen

#include <intrin.h>

signed int RoundFloatToInt(const float & p_Value) {
	return ::_mm_cvt_ss2si(::_mm_load_ss(&p_Value));
}

signed int TruncFloatToInt(const float & p_Value) {
	return ::_mm_cvtt_ss2si(::_mm_load_ss(&p_Value));
}

signed int RoundDoubleToInt(const double & p_Value) {
	return ::_mm_cvtsd_si32(::_mm_load_sd(&p_Value));
}

signed int TruncDoubleToInt(const double & p_Value) {
	return ::_mm_cvttsd_si32(::_mm_load_sd(&p_Value));
}
Ich danke euch für eure Hilfe, in dem Thread ist ja letztendlich doch ein Haufen von Wissen und interessanter Codefragmente über FPU, Bitshifterei mit Gleitkommazahlen und Assemblertrickserei zusammengekommen :)

Falls Interesse daran besteht, wie man komplette Assembler-Dateien zu Visual-C++-Projekten linkt, kann ich noch ein Tutorial drüber schreiben – jetzt weiß ich ja, wie es geht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Gleitkomma- zu Ganzzahlen runden

Beitrag von Krishty »

Dieser Sache scheint man niemals Herr werden zu können -.-

Ich brauche jetzt eine zur 64-Bit-Integer gerundete Gleitkommazahl (die SSE-Intrinsics sind also nicht mehr ausreichend), ich brauche sie unter x64 (also goodbye, Assembler) und ich brauche sie performant.

Ich habe im Verlauf des Threads ja schon festgestellt, dass es dafür keinen portablen Code zu geben scheint – falls hier aber doch nochmal jemand drüber stolpert (oder auch nur über ein halb-portables Intrinsic), sei er ausdrücklich darum gebeten, zu antworten …

Wahnwitz und Idiotie, dass es für jeden Müll Intrinsics und Optimierungen gibt, man aber gerade bei sowas auf einem 24× langsameren, kaum praktisch anwendbaren Umweg beharrt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten