Datenstruktur für Matrizen


  • Mod

    TomasRiker schrieb:

    ... und nun ersetz mal die Template-Klasse durch eine normale Klasse, wo float statt T drinsteht. Es kommt derselbe Code raus. Ebenfalls alles inline reingeklatscht.

    ja genau das war mein beispiel im letzten absatz. wie gesagt, kann er das in zwei implementierungsdateien dann nicht mehr verwenden weil normale implementierungen nicht mehr annonym sind, es compiliert also nicht mal.

    Mit SSE inlined er, ohne SSE nicht.

    wie gesagt, mit den optimierungen die bei jedem spiel dabei sind.

    Also zeig du mir doch bitte mal ein Beispiel, wo er die Methode einer Template-Klasse anders inlined als die Methode der äquivalenten normalen Klasse.

    s.o.


  • Mod

    Pellaeon schrieb:

    Und wie soll man das umgehen? ...

    indem man erst optimiert wenn der code steht und stabil ist.



  • @rapso:
    Es ging doch darum: Du hast gesagt, Methoden von Template-Klassen würden immer inline aufgerufen. Soll dein Beispiel das jetzt widerlegen, oder wie?
    Ich habe testweise die Adder<T> und eine FloatAdder (normale Klasse mit float) genommen. Egal, welche Einstellungen ich nehme: Beide werden gleich geinlined. Wenn er eine Methode bei Adder<T> inlined, dann tut er es auch bei FloatAdder und umgekehrt.


  • Mod

    TomasRiker schrieb:

    @rapso:
    Es ging doch darum: Du hast gesagt, Methoden von Template-Klassen würden immer inline aufgerufen. Soll dein Beispiel das jetzt widerlegen, oder wie?

    das war der beweis um deine behauptung zu wiederlegen dass templateklassen genau wie normale klassen behandelt werden.

    Ich habe testweise die Adder<T> und eine FloatAdder (normale Klasse mit float) genommen. Egal, welche Einstellungen ich nehme: Beide werden gleich geinlined. Wenn er eine Methode bei Adder<T> inlined, dann tut er es auch bei FloatAdder und umgekehrt.

    ja, du hast vollkommen recht.



  • Dein Argument, dass die Template-Klassen pro Objektdatei instanziert werden, ist natürlich auch korrekt.
    Das macht die Objektdateien größer.

    Angenommen wir haben zwei CPP-Dateien A.cpp und B.cpp, die beide jeweils die Template-Klasse Adder<float> benutzen. In A.obj und B.obj ist nach dem Kompilieren jeweils der ganze Code von Adder<float> drin. Natürlich, das ist nicht sonderlich schön.

    Wenn jetzt der Linker kommt und A.obj und B.obj zu einer EXE zusammenlinkt, dann wird er aber doch nur die erste Instanzierung der Klasse nehmen und die andere verwerfen - oder nicht??



  • Wenn ich gewusst hätte was meine Frage für Folgen hat.... 😮



  • Tja, das musst du jetzt ausbaden 😃
    Ist doch egal, man lernt immer was ...



  • Raspo wenn deine Einwände berechtigt wären dürfte man in Template-Klasse keine statischen Variablen benutzen.

    Gilt auch für Template-Funktionen (in Template-Klassen) mit statischen Variablen.

    Der Linker kann (muss es in oben genanntem Fall sogar) Duplikate durchaus erkennen.

    Edit:
    Das Inlining-Problem ist dadurch natürlich nicht behoben. Dazu muss man wie von David gezeigt den Compiler schon zwingen es nicht immer zu inlinen (wobei ich auch schon Funktionen in Template-Klassen direkt reingeschrieben habe und diese nicht geinlined worden).

    Wie gut der VC Linker Strippen kann müsste man mal testen.


  • Mod

    TomasRiker schrieb:

    Wenn jetzt der Linker kommt und A.obj und B.obj zu einer EXE zusammenlinkt, dann wird er aber doch nur die erste Instanzierung der Klasse nehmen und die andere verwerfen - oder nicht??

    der punkt ist (und mehr hab ich nicht behauptet) dass leute ohne es zu wissen trotzdem irgendwelche behauptungen aufstellen z.b. wird (nicht) geinlined... inlined ist schneller/langsammer und glauben ohne es je geprueft zu haben, was irgendjemand anders irgendwo irgendwie gehoert oder gelesen hat ueber templates.

    das resultiert darin dass (im gegensatz zu normalen klassen) das binary aufblaeht und am ende langsammer ist.

    du hast es hier den evolutionsschritt gut gezeigt 🙂

    nur leider die meisten anderen nicht. Ich behaupte nicht dass templates zu verteufeln sind, ich nutze sie selber seit vielen jahren und sage lediglich dass anfaenger damit mehr schlechtes als gutes anstellen.



  • Warst du denn nicht auch einer derjenigen, der ohne es zu wissen eine Behauptung aufgestellt hat? 🙂
    Ansonsten denke ich, können wir es dabei belassen und haben alle was gelernt ...


  • Mod

    TomasRiker schrieb:

    Warst du denn nicht auch einer derjenigen, der ohne es zu wissen eine Behauptung aufgestellt hat? 🙂

    dio mio, No.



  • Äh, sagtest du denn nicht, dass Methoden von Template-Klassen immer inline aufgerufen würden?

    Das könnte man ja denken, wenn man davon ausgeht, dass man Template-Klassen immer direkt an einem Stück mit allen Methoden angeben muss. Muss man aber nicht. Und dann macht es bei der Frage "inline oder nicht?" keinen Unterschied, ob es sich um eine Template-Methode handelt oder um eine normale.



  • Hier gibt's auch ne interessante Diskussion über Templates, Inlining und Code-Bloating:
    Klick


  • Mod

    TomasRiker schrieb:

    Äh, sagtest du denn nicht, dass Methoden von Template-Klassen immer inline aufgerufen würden?

    nein, ich sprach von templates und wie du oben am unterschied von klasse/template gesehen hast, wird das auch so gemacht. da ich deswegen schon 70MB binaries gesehen habe spreche ich auch nicht aufgrund von glauben/vermutung, sondern erfahrung.



  • Bin auch Befürworter von Vector<T, N> und Matrix<T, N, M>.

    Btw.:
    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉
    Vielleicht braucht man ja mal irgendwann eine Farbwert mit 5 oder 6 Channels ^^

    Könnte man nicht sogar die VertexFormate schön mit MPL hinbiegen? Um OnTheFly mit Typedefs sein eigenes VertexFormat definieren zu können.


  • Mod

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?



  • Ja, ich habe für Farben ebenfalls das Vektor-Template genommen. Das war mitunter auch der Grund, warum ich das Template überhaupt erstellt habe - 2D-Vektoren für Texturkoordinaten, 3D für 3D halt 😉 und 4D u.a. für RGBA.



  • rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    Bei XNA haben sie das auch, schreibt sich eigentlich dann ganz nett.
    Außerdem weiß man damit deutlicher dass es ein Farbwert ist.
    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?


  • Mod

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    was sollen diese zwei zeilen beweisen?

    Bei XNA haben sie das auch, schreibt sich eigentlich dann ganz nett.
    Außerdem weiß man damit deutlicher dass es ein Farbwert ist.

    hoe? was soll das aussagen? wo ist der unterschied zu

    typedef Vector<float,3> tyColor3;
    static const tdColor3 White(255, 255, 255);
    static const tdColor3 Red(255, 0, 0);
    

    ?

    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    der zusammenhang entgeht mir.

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?

    je nachdem ob du HDR unterstuetzung brauchst oder nicht.
    gibt ja viele wege nach rom, z.b.

    typedef Vector<Sat<float,0.f,1.f>,3> tyColor3;
    

    btw. opengl limitiert nicht auf 0 bis 1



  • rapso schrieb:

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    was sollen diese zwei zeilen beweisen?

    Mir fällt leider jetzt erst auf dass die zwei Codezeilen wirklich nicht zeigen was ich meinte 😉 ^^
    Ich wollte eigentlich ausdrücken dass man das ganze der Klasse als Membervariable einbauen kann.
    So dass dann möglich ist:

    Color c = Color::White // eben noch mit templates etc.
    driver->clear(Color::White);
    

    Ansonsten (bei benutzung der vectoren für farben) muss man entweder sowas wie einen CommonColors-Namespace machen oder sonst was unschönes.

    rapso schrieb:

    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    der zusammenhang entgeht mir.

    Na der zusammenhang ist, dass bei z.b.

    Driver::clear(Color& color)
    

    Auch nur ein Color-Wert angegeben werden kann, wenn jemand da ein Vector reinhaut gibts ein netten compile-time-error. In Scott Meyers Effective C++ gibts einen Tipp der empfielt für sowas immer eigene Klassen zu schreiben damit der compiler schon zu compile-time weiß ob die Typen stimmen.
    Typedefs sind in C++ einfach nicht sicher.

    rapso schrieb:

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?

    je nachdem ob du HDR unterstuetzung brauchst oder nicht.
    gibt ja viele wege nach rom, z.b.

    typedef Vector<Sat<float,0.f,1.f>,3> tyColor3;
    

    btw. opengl limitiert nicht auf 0 bis 1

    danke, wusste ich nicht.

    Danke für deine antwort 🙂


Anmelden zum Antworten