Autor Thema: Runtime Code Generation?  (Gelesen 11202 mal)

majix

  • Gast
Runtime Code Generation?
« 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

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

Runtime Code Generation?
« am: 09. Juni 2004, 14:20:26 »

Brombaer

  • Gast
Re: Runtime Code Generation?
« Antwort #1 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #2 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

Offline sgt_barnes

  • Mood Master
  • ****
  • Beiträge: 250
  • Der frühe Vogel fängt den Wurm, aber die zweite Maus kriegt den Käse!
    • Profil anzeigen
Re: Runtime Code Generation?
« Antwort #3 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #4 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #5 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

Offline sgt_barnes

  • Mood Master
  • ****
  • Beiträge: 250
  • Der frühe Vogel fängt den Wurm, aber die zweite Maus kriegt den Käse!
    • Profil anzeigen
Re: Runtime Code Generation?
« Antwort #6 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


majix

  • Gast
Re: Runtime Code Generation?
« Antwort #7 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

Offline sgt_barnes

  • Mood Master
  • ****
  • Beiträge: 250
  • Der frühe Vogel fängt den Wurm, aber die zweite Maus kriegt den Käse!
    • Profil anzeigen
Re: Runtime Code Generation?
« Antwort #8 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #9 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #10 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.



Grüße,
Kaya

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #11 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

Brombaer

  • Gast
Re: Runtime Code Generation?
« Antwort #12 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

majix

  • Gast
Re: Runtime Code Generation?
« Antwort #13 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

Brombaer

  • Gast
Re: Runtime Code Generation?
« Antwort #14 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