schnelle mathematik, methodenpointer



  • hallo zusammen,

    hab keinen guten titel gefunden 😃

    mein problem ist ich möchte in meiner engine cpu features nutzen wie zb: 3dnow oder sse oder sonst irgendwas. daraufhin habe ich eine klasse entwickelt die diese features ausliesst und in boolische werte die ergebnisse speichert.
    nun dachte ich mir bei meiner vector klasse das ich ganze mit methodenpointer löse. ich dacht mir das ich ctor der vector klasse abfrage welche features vorhanden sind und dann die entsprechenden methoden setzte. ist das der richtige (schnellste) weg dieses zu tun oder findet jemand eine bessere lösung.

    ps: wie würdet ihr der vector klasse die klasse "cpu" bekannt machen.
    [edit]
    vielleicht cpu als singleton machen ?
    [/edit]

    // pseudo code
    class Cpu
    {
    	public:
    		Cpu() { /* hier wird die cpu gelesen */ } 
    
    	public:
    		bool 	m_bSSE;
                    bool	m_b3DNow;
    };
    
    class Vector
    {
    	public:
    		Vector()
                    { if(cpu.m_SSE)
                         pfCross= &Vector::Cross1;
                      else
                         pfCross= &Vector::Cross2;
                    }
    
    		// kreuzprodukt
    		void Cross(const Vector &v1, const Vector &v2)
                        { (this->*pfCross)(v1, v2); }
    
    	private:
                   void (Vector::*pfCross)(const Vector &v1, const Vector &v2);
    
    	       void Cross1(const Vector &v1, const Vector &v2);
    	       void Cross2(const Vector &v1, const Vector &v2);
    };
    


  • würde das anders machen, CPU ist die Basisklasse und von ihr sind alle CPU-Typen abgeleitet, dabei enthält CPU schon alle operationen als funktionen, rein virtuell, versteht sich und die abgeleiteten klassen müssen diese funktionen dann prozessorspezifisch implementieren. Dann brauchsz du nur noch eine globale Funktion, die je nach CPU-Typ eine entsprechende Instanz der vorhanden CPU zurückgibt (wenns halt ein PIII ist wird ein Ptr auf eine Instanz von Pentium3 zurückgegeben) Das ganze sollte man sinnvollerweise (wie du schon gesagt hast) als Singleton implementieren.

    trifft sicher dein problem nicht ganz, wäre aber eine schöne transparente möglichkeit, wenn du allgemeine operationen hast, die entsprechend optimiert werden könnten...

    und wenn du es so machst, wie bisher, dann mach die variablen um himmels willen privat und implementiere stattdessen inline-funktionen, die die entsprechenden bools zurückgeben... jede dumme funktion könnte sonst einfach die variablen ändern...



  • ich word ein bündel von templates machen, in verschieden libs packen und zur laufzeit entscheiden, welche genehmt werden soll.
    edit: oder für jede combo ne eigene exe raushauen, das macht die cd wenigstens nicht ganz so leer. und cracker haben auch mehr arbeit, gleich 120 exes zu knacken.



  • todo schrieb:

    würde das anders machen, CPU ist die Basisklasse und von ihr sind alle CPU-Typen abgeleitet, dabei enthält CPU schon alle operationen als funktionen, rein virtuell, versteht sich und die abgeleiteten klassen müssen diese funktionen dann prozessorspezifisch implementieren. Dann brauchsz du nur noch eine globale Funktion, die je nach CPU-Typ eine entsprechende Instanz der vorhanden CPU zurückgibt (wenns halt ein PIII ist wird ein Ptr auf eine Instanz von Pentium3 zurückgegeben) Das ganze sollte man sinnvollerweise (wie du schon gesagt hast) als Singleton implementieren.

    trifft sicher dein problem nicht ganz, wäre aber eine schöne transparente möglichkeit, wenn du allgemeine operationen hast, die entsprechend optimiert werden könnten...

    stimmt trifft es nicht ganz. habe auch was entscheidendes vergessen. 😮
    dem user der engine steht natürlich nur die vector klasse zur verfügung.
    und diese sollte je nach prozessor entsprechende operationen durchführen.

    todo schrieb:

    und wenn du es so machst, wie bisher, dann mach die variablen um himmels willen privat und implementiere stattdessen inline-funktionen, die die entsprechenden bools zurückgeben... jede dumme funktion könnte sonst einfach die variablen ändern...

    was nur pseudo code 😉

    volkard schrieb:

    ich word ein bündel von templates machen, in verschieden libs packen und zur laufzeit entscheiden, welche genehmt werden soll.
    edit: oder für jede combo ne eigene exe raushauen, das macht die cd wenigstens nicht ganz so leer. und cracker haben auch mehr arbeit, gleich 120 exes zu knacken.

    wie würdest du das mit templates lösen ? (bin nicht so bewandert mit templates, weiss glaub ich nur das nötigste)



  • Was ihr alle hier für einen Schwachsinn verzapft, echt köstlich!

    Funktionspointer, davon mal gehört? Geile Dinger



  • nix da schrieb:

    Was ihr alle hier für einen Schwachsinn verzapft, echt köstlich!

    Funktionspointer, davon mal gehört? Geile Dinger

    Klar - ist aber ein indirekter AUfruf der nicht geinlinet werden kann. Das kann uU etwas doof werden.



  • Shade Of Mine schrieb:

    nix da schrieb:

    Was ihr alle hier für einen Schwachsinn verzapft, echt köstlich!

    Funktionspointer, davon mal gehört? Geile Dinger

    Klar - ist aber ein indirekter AUfruf der nicht geinlinet werden kann. Das kann uU etwas doof werden.

    Manchmal muss man eben Opfer bringen.



  • nix da schrieb:

    Manchmal muss man eben Opfer bringen.

    Jo. Manchmal muss man das Programm langsamer machen, wenn man cool sein will.



  • ISSE und ISSE2 sowie 3DNow! machen das an Speed locker wieder Wett. Wo ist das Problem? Hier für ist auch ein Profiler wieder sehr gut.



  • nix da schrieb:

    ISSE und ISSE2 sowie 3DNow! machen das an Speed locker wieder Wett. Wo ist das Problem? Hier für ist auch ein Profiler wieder sehr gut.

    ich sagte ja auch _manchmal_ 🙂
    Funktionszeiger sind aber (Achtung: schock für dich) nicht die ultimative Antwort. Und was anderes habe ich auch nicht gesagt. 🙂



  • sind jetzt funktionpointer eine alternative ?!? und wie würdet ihr das implementieren ?

    ps: cool muss ich nicht mehr sein, aus dem alter bin ich glaub ich raus 😃



  • wie würdest du das mit templates lösen ? (bin nicht so bewandert mit templates, weiss glaub ich nur das nötigste)

    Er meint per Templatespezialisierung. Wenn dein Program open Source ist und auf dem Processor auf welchem es später laufen soll kompiliert wird ist das eindeutig die beste Lösung : Problem man kann nur zwischen CPUs wählen at compile time. Beispiel:

    const int p3=1;
    const int p4=2;
    const int athlon=3;
    //...
    template<int cpu_type>
    class basic_cpu{
    public:
      void foo(){...}
    };
    template<>
    class basic_cpu<p3>{
    public:
      void foo(){...}
    };
    template<>
    class basic_cpu<p4>{
    public:
      void foo(){...}
    };
    template<>
    class basic_cpu<athlon>{
    public:
      void foo(){...}
    };
    basic_cpu<CPU_TYPE> cpu;
    

    Und du switchs zwischen den CPUs indem du das CPU_TYPE Macro definierst, im besten in einem Makefile. Zum Beispiel:

    #define CPU_TYPE p4
    

    Der große Vorteil hier ist dass die Funktionen direkt aufgerufen werden und kein Indirection nötig ist, desweiteren wird automatisch der Code für die anderen CPUs rausgehaun.

    Wenn du nun allerdings Closed Source hast kommst du wohl nicht um Vererbung herum:

    class Cpu{
    public:
      virtual void foo()=0;
    };
    class P3:public Cpu{
    public:
      void foo(){...}
    };  
    class P4:public Cpu{
    public:
      void foo(){...}
    };
    Cpu*cpu;
    int main(int argc,char**argv){
      if(!strcmp(argv[1],"P3"))
        cpu=new P3;
      else if(!strcmp(argv[1],"P4"))
        cpu=new P4;
      //...
      delete cpu;
      return 0;
    };
    


  • Irgendwer schrieb:

    ;
    int main(int argc,char**argv){
      if(!strcmp(argv[1],"P3"))
        cpu=new P3;
      else if(!strcmp(argv[1],"P4"))
        cpu=new P4;
      //...
      delete cpu;
      return 0;
    };
    
    #define elseif else if
    ...
    if(!strcmp(argv[1],"P3"))
      Game<P3>.run();
    elseif(!strcmp(argv[1],"P4"))
      Game<P4>.run();
    else
      Game<DEFAULT_PROCESSOR>.run();
    

    und das evtl sogar mit mehr als einem template-parameter.



  • ich glaub so langsam zeilt der thread in eine andere richtung ab.
    bin vielleicht auch ich dran schuld. 😃

    die engine wird als bibliothek weitergegeben, der user "sieht" dann die vectorklasse und kann sich damit grün und blau rechnen. diese sollte dann intern zur laufzeit die cpu ermitteln und dann die entsprechenden berechnungen und den vorhandenen features machen.

    ich glaub ich bleib doch bei der variante im ctor der vector klasse jedesmal die cpu klasse aufzurufen und dann entsprechend die pointer zu setzen. (wie oben beschrieben)



  • dann haste halt kein inlining mehr und der optimerer ist für alles weitere blind. das ist ein großer schaden.



  • volkard schrieb:

    dann haste halt kein inlining mehr und der optimerer ist für alles weitere blind. das ist ein großer schaden.

    hab ich doch sowieso nicht, da meine methoden ausserhalb der klasse definiert
    werden, oder nicht ?



  • miller_m schrieb:

    ich glaub ich bleib doch bei der variante im ctor der vector klasse jedesmal die cpu klasse aufzurufen und dann entsprechend die pointer zu setzen. (wie oben beschrieben)

    Kann den Code aber langsamer machen - würde ich erst profilen.
    volkards Ansatz hat 0 Overhead.

    miller_m schrieb:

    hab ich doch sowieso nicht, da meine methoden ausserhalb der klasse definiert
    werden, oder nicht ?

    Hängt vom Compiler ab. VC++ hat zB 'Whole Programe Optimization' - der kann das. Andere nicht.

    Theoretisch spricht nämlich nichts dagegen.



  • Shade Of Mine schrieb:

    Kann den Code aber langsamer machen - würde ich erst profilen.
    volkards Ansatz hat 0 Overhead.

    aber der user der bibilothek müsste sich dann entscheiden welche vectorklasse er benutzen will. ?!?

    Shade Of Mine schrieb:

    Hängt vom Compiler ab. VC++ hat zB 'Whole Programe Optimization' - der kann das. Andere nicht.

    benutz keinen vc sondern mingw

    Shade Of Mine schrieb:

    Theoretisch spricht nämlich nichts dagegen.

    gegen was ?


Anmelden zum Antworten