Funktion optimieren?



  • Geo schrieb:
    2. Output=result; hat die (hier) gewünschte Wirkung.

    ...

    Dann ist die gewünschte Wirkung aber eine sehr seltsame. C++ hat immer noch Call-by-value, dh output wird nicht verändert.

    Richtig erkannt, wenn Output==NULL ist, wird Output hier zu einer normalen Variablen "degradiert".



  • zu der Output-Geschichte: Sorry, ich war etwas zu voreilig.

    Shade: Achso. Nein, iSAK hat seine Implementation schon gepostet:

    class CMatrix {
      public:
        float _11, _12, etc...;
    };
    

    Wenn man keinen besonders böswilligen Compiler vor sich hat funktioniert meine Variante. Ich hab ja auch dazugesagt, das es nicht standardkonform ist, aber bei Hochleistungsanwendungen wie Spielen, die noch dazu auf eine sehr enge Plattformauswahl eingeschränkt sind, spielt Portabilität nicht so die Rolle.



  • Bashar schrieb:

    Shade: Achso. Nein, iSAK hat seine Implementation schon gepostet:

    Oh, das habe ich übersehen. Dann ist deine Variante natürlich OK.



  • Was ist an Bashars Variante überhaupt anzuzweifeln? Kann mich mal er aufklären?



  • die einzelnen floats (_11, _12 usw.) müssen nicht zwingend lückenlos aufeinander im Speicher liegen, das kann der Compiler nach gutdünken entscheiden. Beispielsweise sind auf heutigen PCs 32-Bit-Speicherzugriffe auf Daten, die an durch 4 teilbaren Adressen liegen, deutlich schneller als wenn sie an krummen Adressen liegen. Da ist es also sinnvoll, eine char und eine int-Variable intern so zu verpacken:

    struct A {
      char c;
      char __dummy[3];
      int i;
    };
    

    Wenn ein Compiler Lust hat, kann er das auch mit lauter floats machen, der Standard verbietet es nicht.



  • Mis2com schrieb:

    casts sind langsam!

    reinterpret? lol?

    sagt jetzt nicht das ist UNSINN! TGGC hats bewiesen!

    LOL

    1. lies mal das 2. wort von reinterpret_cast.

    2. Im gegensatz zu dir hat er mal was bewiesen und zu ende gemacht,



  • Bist du so dumm, oder tust du nur so. da steht ganz offensichtlich "float*" !!! Das heit, es findet keine umwandlung, sondern tatsächlich eine reine reinterpretation statt!!! und die kosten gar nichts. Überhaupt nichts. Wogegen deine Version jenach dem ob der erste Parameter NULL ist oder nicht eine oder zwei komplette Kopien der Matrix anlegt.

    Und TGGC's Beispiel ist korrekt, hat aber überhaupt nichts mit dem hier gezegten zu tun. Dort wurde tatsächlich umgewandelt.

    😡 👎



  • cast ist cast, ob reinterpret, static, dynamic und co. cast ist cast



  • Schafft es mal endlich einer, diesen Thread zu schließen und unregistrierte, grüne kleine Wichte mit blauen Haaren aus diesem Forum zu verbannen? 👍



  • wieso damit wieder so ein Scheiss wie im Grafik und Spieleprogrammierforum passiert?

    Da schaffen die Mods ja nix! Da wird seit Tagen rumgeflamet zwischen diversen Membern und die Mods oder Admins greifen nicht ein oder gucken sich den shice erstmal an!

    Für mich sind einige Mods hier sehr inkompetent!!!!! Und das selbe würde hier auch Passieren!!!!



  • Ein für alle Mal, TGGC hat nur den static_cast überprüft, oder vielleicht den C-Cast der diesem entspricht.
    Nur weil an 2. Stelle cast steht, bedeutet das noch lange nicht, dass das Teil langsam ist.
    Und anstatt jetzt pausenlos einzuwenden, dass dieser ,,Cast'' langsam ist, solltest du es mal selber ausprobieren, dann können wir gerne weiterreden.

    Unter diesen Voraussetzungen hat eine Diskussion keinen Sinn.

    So, ich habe selber mal getestet:

    #include <iostream>
    #include <windows.h>
    
    int main()
    {
    	const double NPASSES = 100000000.;
    	float  f = 100;
    	int    n;
    	DWORD dw1, dw2;
    
    	dw1 = GetTickCount();
    
    	for(int f_n = 0; f_n < NPASSES; ++f_n)
    		n = static_cast<int>(f);
    
    	dw2 = GetTickCount();
    
    	std::cout.flags(std::ios::fixed);
    
    	std::cout << "Dieser Cast benötigt " << (dw2-dw1)/NPASSES << " Millisekunden.\n";
    
    	return 0;
    }
    

    Ich weiß ja nicht, was du unter schnell verstehst...

    #include <iostream>
    #include <windows.h>
    
    int main()
    {
    	const double NPASSES = 100000000.;
    	float* pf = new float;
    	int*   pn;
    	DWORD dw1, dw2;
    
    	dw1 = GetTickCount();
    
    	for(int f_n = 0; f_n < NPASSES; ++f_n)
    		pn = reinterpret_cast<int*>(pf);
    
    	dw2 = GetTickCount();
    
    	std::cout.flags(std::ios::fixed);
    
    	std::cout << "Dieser Cast benötigt " << (dw2-dw1)/NPASSES << " Millisekunden.\n";
    
    	return 0;
    }
    

    Gemessen:

    static_cast: 0.000054 ms
    reinterpret_cast: 0.000010 ms

    Wobei mein PC ein Athlon mit 900 MHz ist...

    MfG MAV



  • Mis2com schrieb:

    Ein für alle Mal, TGGC hat nur den static_cast überprüft, oder vielleicht den C-Cast der diesem entspricht.

    Die Umwandlung float <-> int ist deshalb 'lahm' weil die CPU das nicht so einfach kann: denn ein float sieht ja intern anders aus als ein int.

    Bei Zeigern existiert für die CPU aber keine Typinformation - denn für die CPU sind alle Zeiger void* -> erst wenn wir p schreiben, holt die CPU die Daten aus dem RAM. Und da findet keine Umwandlung statt. Schau dir mal die Ausgabe von
    float
    f=new float(3);
    cout<<*reinterpret_cast<int*>(f)
    delete f;
    an.

    Das Ergebnis wird nicht 3 sein.



  • Athlon 1700+ (~1,5Ghz)

    static: Dieser Cast benötigt 0.000031 Millisekunden.
    reinterpret: Dieser Cast benötigt 0.000007 Millisekunden.

    Ich hoffe du siehst es endlich ein.
    Man kann doch nicht so sturköpfig sein 😕



  • ich würd sagen das ein reintepret cast häufig garkeine zeit benötigt, weil er nur auf compiler eben existiert (was natürlich nicht garantiert ist aber ich sehe keinen grund das anders zu machen).

    und überhaupt was soll

    iSAK schrieb:

    meine CMatrix:

    class CMatrix
    {
    public:
    	float	_11, _12, _13, _14;
    	float	_21, _22, _23, _24;
    	float	_31, _32, _33, _34;
    	float	_41, _42, _43, _44;
    };
    

    konkret bringen? warum nicht von anfang an ein array?

    und noch zum thema casts und geschwindigkeit. ich "beweise" hier einfach mal, dass code mit reinterpret_cast schneller ist als ohne.

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
       float a[100];
       int b[100];
       long long start, end;
    
       __asm__ __volatile__ ("rdtsc" : "=A" (start) );
    
       for(int i=0;i<1000;++i)
          copy(&b[0], &b[100], &a[0]);  
    
       __asm__ __volatile__ ("rdtsc" : "=A" (end) );
    
       cout << "ohne cast: " << end-start << endl;
    
       __asm__ __volatile__ ("rdtsc" : "=A" (start) ); 
    
       for(int i=0;i<1000;++i)
          copy(&b[0], &b[100], reinterpret_cast<int*>(&a[0]));
    
       __asm__ __volatile__ ("rdtsc" : "=A" (end) );
    
       cout << "reinterpret_cast: " << end-start;
    
       return 0;
    }
    

    im gcc kompiliert:

    ohne cast:       1322467
    reinterpret_cast: 269098
    

    mit -O3 holt die ohnecast variante etwas auf:

    ohne cast:        331201
    reinterpret_cast: 193134
    

    man muss nur das richtige messen, dann kann man beweisen, was man will. 😃



  • der_held schrieb:

    Bist du so dumm, oder tust du nur so

    iSAK schrieb:

    cast ist cast, ob reinterpret, static, dynamic und co. cast ist cast

    muss ich noch viel mehr sagen? dynamic_casts führt zu laufzeit Typtests durch, is deshalb prinzipiell schonmal langsamer.

    und

    float x;
    reinterpret_cast<int>(x); // Hier muss ein int in eine float gewandelt werden
    
    float * x;
    reinterpret_cast<int * >(x); // Hier muss gar nichts gemacht werden
    

    Das kann doch wirklich nicht so schwer sein.

    Du zitierst Threads, die nichts mit dem Thema zu tun haben. Du stellst behauptungen auf, ohne es selbst je getestet zu haben. Was soll das? Verarschen kann ich mich selbst.



  • Kann man mit reinterpret_cast float nach int casten???

    @Shade_Of_Mine:
    Das leuchtet natürlich ein.



  • n, oder zumindest nicht so, wie du es erwartest. reinterpret lässt den Speicher völlig unberührt, nur wird er anders interpretiert (wie der name schon sagt). D.h. reinterpret_cast<float>(7) != 7.0 (sollte es auf jeden fall sein) weil die Variable intern anders dargestellt wird.
    geloescht


Anmelden zum Antworten