mood-indigo.org - Das unabhängige Silicon Graphics User Forum

Irix => Programmieren, Kompilieren => Thema gestartet von: majix am 09. Juni 2004, 14:20:26

Titel: Runtime Code Generation?
Beitrag von: majix am 09. Juni 2004, 14:20:26
Mal wieder eine Frage: Als ein ultimatives Optimierungstool stelle ich mir im Augenblick einen "runtime code compiler" vor, d.h. einen compiler, der zur Laufzeit eines Programmes neuen Code erzeugen kann.

Was will ich damit machen? Ich habe ein Programm geschrieben, das 3DS Files laden und mittels OpenGL darstellen kann (im Augenblick nur utner Windows). Jetzt hat so ein Modell natürlich verschiedene Texturen etc, d.h. ich muss in einer Schleife alle Meshes einzeln durchlaufen und dann abchecken, welche OpenGL States neu zu setzen sind und dann das Mesh rendern. Aber eigentlich ändern sich diese Entscheidungen ja nie, welche States wann neu zu setzen sind.

Meine Idee ist es nun, zur Laufzeit des Programmes diekt nach dem Laden des Modells Code zu erzeugen, der dann mehr oder weniger nur noch OpenGL Aufrufe enthält. D.h. dieses lästige Schleife würde vollständig entfallen.

Nur: Wie erzeuge ich zur Laufzeit Code, und dazu noch in einer portierbaren Art und Weise? Meine Vorstellung wäre irgendwie so, dass ich zur Laufzeit einen ASCII-Text mit Quellcode erzeuge, den dann durch einen Compiler jage, und den erzeugten Code dann einfach aufrufe. Java und .NET kann sowas wohl, aber beides ist für meine Zwekce ungeeignet.

Googeln brachte durchaus zu Tage, dass ich nicht der einzige bin, der sich für solche Techniken interessiert, es gibt da einige Forschungs- und Entwicklungsarbeit, und auch ein paar Projekte. Nur was richtig passendes habe ich leider noch nicht gefunden.

Meine Anforderungen wären:
- Das Tool/Die Library sollte portabel sein (Windows, Linux, IRIX, Mac OS X)
- Man sollte irgendwie einen Quelltext als Eingabe reinstecken können, und eine fertig compilierte Funktion herausbekommen.
- Man muss auf jeden Fall OpenGL Funktionen aufrufen können

Hat da jemand Erfahrung und kennt ein passendes Tool?

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 09. Juni 2004, 16:03:47
Hallo Kaya,

soweit ich weiss gibt es sowas nicht. Ich kann mir auch nicht vorstellen, dass es wirklich viel Sinn ergibt da viel Zeit reinzustecken, denn in Zukunft wird eher die CPU zum Bottleneck, da machts Deine Schleife auch nicht aus. Zusätzlich optimieren alle ordentlichen Graphikprogramme die Statechanges, da ein Statechange eine maximal teuer und damit zu vermeidende Operation ist. Was Du suchst funktioniert auch nur für statische Objekte, bei dynamischen Szenen rentiert sich der Aufwand nicht mehr.

Eine Möglichkeit wäre einfach 1x zu rendern und den OpenGL-Stream abzugreifen (oder sich ne Dummy GL-Schnittstelle zu schreiben). Viel Spass wird das aber sicher nicht machen, denn die GL hat recht viele Befehle mittlerweile.

Gruß

Matthias
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 09. Juni 2004, 16:21:19
Klar, das hilft nur bei statischen Objekten - aber das sind ja die meisten Objekte.

Momentan habe ich mir eine Art Command-Stream gebastelt, da steckt man Anfangs lauter Meshes rein, dann sagt man "bitte einmal optimieren", dann wird daraus eine Befehlsfolge erzeugt, die die Statechanges minimiert (durch umsortieren der Meshes etc). Nur diese Befehlsfolge muss ich im Augenblick noch interpretieren (switch case-Konstruktion). Mir wäre es lieber, wenn der Command-Stream ein fertiges Programm für die CPU wäre.

Im Prinzip will ich sowas wie eine Display-List für jedes Modell, allerdings mit etwas mehr Optionen: Ich kann z.B. in den Command-Stream auch Zeiger auf Matrizen einbauen, so dass dann jedes der jeweils aktuelle Wert einer Matrix gesetzt wird. So kann man durchaus auch animierte Objekte derart optimieren.

Mein ideales Ziel ist nämliches folgendes: Die CPU dreht die Däumchen, während die GPU ins Schwitzen kommt. Denn erstens sehe ich nicht ein, wieso man eine schnelle CPU für Grafik braucht, zweitens kann ich die CPU Zeit dann für Simulation verwenden.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: sgt_barnes am 09. Juni 2004, 17:15:13
Hola! DAS klingt mal richtig interessant!  :D

Also wenn es kein Problem ist, diese Text-Datei zu erzeugen, und zu kompilieren, dann linke das ganze doch einfach zu einer DLL (bzw. eine schared object) und lade es nach (unter Windoof mit LoadLibrary() und unter UNIX mit dlopen() ).

Alles was Du dann noch brauchst, ist ein Interface, mit dem Du leben kannst. Für's erste sollte eine "render()"-Funktion reichen. Später wirst Du wohl auch andere Parameter dynamisch gestalten wollen.

Das ist der typische Plugin-Ansatz, und der hat bekanntlich mehrere Vorteile:

- genauso schnell wie der Rest des Programms (weil native code und kein Interpreter)
- flexibel ohne Ende
- der dynamische Linker erledigt den Grossteil der Arbeit für Dich

Das einzige Problem ist, dass es nicht ganz so einfach ist, das plattformunabhängig hinzukriegen. Das ist aber auch lösbar.

Ich werde immer gespannter drauf, was Du da produzierst...

MfG,
Tilmann
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 09. Juni 2004, 22:13:50
@sgt_barnes:
An den Ansatz habe ich auch gedacht - ist auf jeden Fall gangbar, allerdings setzt das dann immer eine vollständige C++-Installation auf Anwenderseite voraus.

Aber da fällt mir ein: Gibt es denn nicht irgendwelche andere (Skript)-Sprachen, die OpenGL unterstützen und direkt compilieren?

Das einzige Projekte, das in etwa dem Nahe kommt, was ich will, ist http://www.dyninst.org/. Aber das scheint mir sehr auf Debugging zugeschnitten zu sein... insbesondere kann man damit wohl gut ein Programm modifizieren, aber keine Subroutine vollkommen neu erstellen.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 10. Juni 2004, 22:05:52
So, mal ein kleines Update zu dem Problem: Da ich ja eigentlich ziemlich einfache Programme ohne Sprünge und schleifen erzeugen will, kann ich das eigentlich auch selber machen. Es handel sich ja eigentlich nur um eine Folge von Funktionsaufrufen, das sollte nicht allzu schwierig oder aufwändig werden.

Das muss ich dann zwar für jede Plattform neu machen, aber der Aufwand sollte relativ klein sein. Und als Kompatibiltätsmodus kann ich ja immer noch mein altes System verwenden.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: sgt_barnes am 11. Juni 2004, 14:21:12
Zitat
An den Ansatz habe ich auch gedacht - ist auf jeden Fall gangbar, allerdings setzt das dann immer eine vollständige C++-Installation auf Anwenderseite voraus.


Hm, das stimmt natürlich! Browser-Plugins werden nunmal schon binär ausgeliefert und nicht beim Anwender kompiliert...

Zitat
Da ich ja eigentlich ziemlich einfache Programme ohne Sprünge und schleifen erzeugen will, kann ich das eigentlich auch selber machen. Es handel sich ja eigentlich nur um eine Folge von Funktionsaufrufen, das sollte nicht allzu schwierig oder aufwändig werden.

Das muss ich dann zwar für jede Plattform neu machen, aber der Aufwand sollte relativ klein sein. Und als Kompatibiltätsmodus kann ich ja immer noch mein altes System verwenden.


Wenn Du das richtig anstellst, so mit Parser und abstraktem Syntaxbaum und so wie in der Compilerbau-Vorlesung, brauchst Du nur die Code-Generierung portieren. Und die braucht ja dann auch nur einen Stack zusammenbauen und eine Funktion nach der anderen aufrufen. Und für den Rest gibt es Yacc und Bison.

Das grösste Problem dürfte in dem Zusammenhang werden, den genrierten Code zu laden und dann zu linken (Du musst ja wissen, wo Du hinspringen musst).

Dieses dyninst-Projekt kling vielversprechend, das sollte man sich wohl auch mal genauer angucken. Aber die frickeln wohl eher Code in schon kompilierte Programme, um zum Beispiel einen Callstack ausgeben zu können, wenn die Applikation crasht. Könnte trotzdem interessant für Dich sein.

MfG,
Tilmann

Titel: Re: Runtime Code Generation?
Beitrag von: majix am 11. Juni 2004, 15:01:27
Zitat

Das grösste Problem dürfte in dem Zusammenhang werden, den genrierten Code zu laden und dann zu linken (Du musst ja wissen, wo Du hinspringen musst).

Ich habe mir jetzt was relativ einfaches einfallen lassen, da werde ich diese Probleme elegant umgehen. Ich habe mir eine Klasse gebastelt ("Assembler"), in die ich die zu erzuegenden Call-Befehle über Methoden einfüge - als Parameter übergibt man einfach den Zeiger auf die aufzurufende Funktion, plus Prameter - damit entfällt das Linken. Daraus muss ich jetzt nur noch die x86 Opcodes in einem Speicherblock generieren, und dann sollte ich ja direkt in diesen Speicherblock reinspringen können (über einen Funktionspointer auf diesen Speicherblock).

Zitat

Dieses dyninst-Projekt kling vielversprechend, das sollte man sich wohl auch mal genauer angucken. Aber die frickeln wohl eher Code in schon kompilierte Programme, um zum Beispiel einen Callstack ausgeben zu können, wenn die Applikation crasht. Könnte trotzdem interessant für Dich sein.

Ist schon interessant, aber wie Du selber sagst, der Schwerpunkt liegt auf dem Modifizieren bereits laufender Programme.

Ich habe noch ein wenig gegoogelt, auch sehr Interessant ist vcode http://www.pdos.lcs.mit.edu/~engler/pldi96-abstract.html. Aber wie gesagt, ich denke ich habe eine ganz nette Lösung gefunden, ich muss sie nur noch fertig stellen, aber das sollte relativ schnell gehen. Bei Interesse kann ich ja mal ein paar Details posten.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: sgt_barnes am 11. Juni 2004, 17:39:44
Zitat
Bei Interesse kann ich ja mal ein paar Details posten.


Klar, lass sehen sobald Du was hast! :D

Schönes Wochenende,
Tilmann
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 12. Juni 2004, 16:55:24
So, ich habe gesiegt :) Ich habe mir einen winzig-Assembler geschrieben, mit dem ich simple Folgen von Call-Statements erzeugen kann.

Auf das wesentliche gebracht sieht das so aus, wobei es eine Programm-Klasse gibt.


class Assembler  {
private:
     ...
public:
     void  clear();
     void finish();

     Program* compile();

     void asmCall(void (__stdcall *)());

     template<typename P1>      
     void asmCall(void (__stdcall *adr)(P1), P1 p1);

     template<typename P1, typename P2>
     void asmCall(void (__stdcall *adr)(P1 ,P2 ), P1 p1, P2 p2);

     void asmReturn();
};


Als ein kleines (nicht direkt lauffähiges) Programm zum Download habe ich ein kleines ZIP erstellt:

http://obsolete.majix.org/mood/assembler.zip

Durch relativ kleine Änderungen (Container-Klassen und namespaces) sollte man das auch in eigenen Projekten verwenden können. Compiliert unter VC++ 6.0, ich weiß nicht wie es mit GCC aussieht, denn die Templates haben auch mal wieder etwas gebraucht, bis VC++ sie gefressen hat.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 12. Juni 2004, 21:54:31
So, und was kann man jetzt damit machen? Bis jetzt noch nichts weltbewegends, aber immerhin ein 3DS-File laden und anzeigen.

(http://obsolete.majix.org/mood/flieger.klein.gif) (http://obsolete.majix.org/mood/flieger.gif)

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 02. Januar 2005, 00:22:03
So, zwischen den Jahren habe ich endlich mal die Zeit und Muße gefunden, erste Resultate meiner Programmieranstrengungen zu veröffentlichen. Zwei kleine Test-Programme und den ganzen Quellcode (BSD-Lizenz) könnt ihr unter http://magnum.dimajix.de/download/ herunterladen.

Ist bis jetzt noch nichts großartiges, aber ich hoffe dass demnächst etwas spektauklärere Dinge fertig werden. Als nächstes sind transparente Meshes (die müssen etwas aufwändiger behandelt werden) und GLSL-Shader geplant.

Viele Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 02. Januar 2005, 11:10:07
Gratulation Kaya,

Wie willst Du denn die transparenten Meshes behandeln ? Als Einzeldreiecke rendern oder hast Du sogar vor sich schneidende Dreiecke zu Zerlegen ? Sortierung dürfte ja klar sein.

Gruß

Matthias
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 02. Januar 2005, 14:32:42
Hi Matthias,

die Transparenten Meshes wollte ich zuerst mal nur die vollständigen Batches sortieren, in der Hoffnung, dass man damit schon akzeptable Ergebnisse erzielen kann. Dreiecke zerschneiden möchte ich auf keinen Fall, und einzelne Dreiecke sortieren möchte ich auch vermeiden. Wobei man das auch adaptiv machen kann: Falls sich zwei Batches überscheiden, dann kann man diese wirklich zusammen sortieren, ansonsten nicht.

Ich stelle mich da auf den Standpunkt, dass man bei diesem Thema eben auch von den Grafikern selbst eine direkte Unterstützung benötigt - bei Spielen eine übliche Einstellung ;)

Ich werde jedenfalls erstmal die einfachste Implementierung machen, und dann mal sehen, wie es ausschaut.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 02. Januar 2005, 17:26:36
Hallo Kaya,

das ist auch der Ansatz den OpenSG wählt, aber es gibt durchaus genug Fälle wo es fehlschlägt. Für den Benutzer natürlich lästig, da er (auch wenn durch GUI problemlos und einfach möglich) per Hand die entsprechenden Meshes zerlegen muss.

Meiner Meinung nach gehört die Dreieckssortierung zumindest in die Engine, die Zerlegung einzelner Dreiecke jedoch nicht.

Gruß

Matthias
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 03. Januar 2005, 13:34:59
So oder so werde ich zuerst die einfachste Lösung implementieren, ist ja schließlich die natürliche Reihenfolge. Eine Sortierung der einzelnen Dreiecke kann ich noch verhältnismäßig einfach einbauen, aber Dreiecke zersägen ist wird mir definitiv zu kompliziert und frisst bestimmt auch einiges an Performance.

Aber zuerst muss ich noch einen Bug in meinem Octree fixen, denn irgendwo verschwinden einige der eingefügten Objekte...

Grüße,
Kaya

Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 03. Januar 2005, 13:41:02
Zitat

Aber zuerst muss ich noch einen Bug in meinem Octree fixen, denn irgendwo verschwinden einige der eingefügten Objekte...


Auch ne Möglichkeit Performance zu gewinnen ;D

Matthias
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 04. Januar 2005, 13:01:30
Hmmm... nachdem ich diesen Performnce-Booster beseitigt habe, bin ich nun doch etwas enttäuscht von der Geschwindigkeit. Ich schaffe gerade mal geschätzt rund 40Mio Dreiecke/Sekunde darzustellen, obwohl meine Karte laut Hersteller 480Mio Dreiecke/Sekunde transformieren kann. (Die Dreiecke sind winzig, und viele sogar gar nicht auf dem Screen, es sollte also die die reine Vetex-Transformations-Leistung ausschlaggebend sein).

Aber immerhin ist das ganze noch wesentlich langsamer, wenn ich das Modell nicht optimiere, d.h. mein Optimizer bring auf alle Fälle was.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 04. Januar 2005, 17:49:19
Vielleicht eine doofe Frage,

aber warum renderst Du Dreiecke die nicht sichtbar sind ? rekursives Frustum-Culling über die Bounding-Boxen sollte machbar sein.

Die theoretischen Werte der GraKa-Hersteller kann man knicken, das sind rein akademische Zahlen z.B. ohne Statechanges und maximal grosse Dreiecksstripes etc. pp.

Matthias
Titel: Re: Runtime Code Generation?
Beitrag von: majix am 04. Januar 2005, 19:40:18
Wieso ich Dreiecke zeichne, die nicht sichtbar sind? Weil das Culling noch nicht vollstädnig implementiert ist ;) Aber das kommt auch bald, es ist halt etwas lästiger Kram mit den ganzen Schnittroutinen... Der Octree ist ja mittlerweile fertig, nur die Culling-Routinen sind bis jetzt nur Dummies.

Im Augenblick sind die Meshes auch noch nicht gestrippt, da sollte man auch noch mal ein Quäntchen Performance rausholen können.

Grüße,
Kaya
Titel: Re: Runtime Code Generation?
Beitrag von: Brombaer am 04. Januar 2005, 20:02:52
Naja, bevor sowas nicht implementiert ist, brauchen wir ja über Performance nicht zu reden ;)

Viel Spass beim weiteren Implementieren. Ich hoffe dass lohnt sich auch in finanzieller Hinsicht ...

Matthias