Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Hallo Leute,
ich habe festgestellt, dass alleine durch das einbinden der dglOpenGL.pas die Exe um knappe 105KB anwächst. Ist natürlich in der heutigen Zeit nicht wirklich viel, meiner Meinung nach aber unnötig. Natürlich könnte man nur jede benötigte Konstante und Funktion manuell einbinden. Was aber mitunter sehr aufwendig sein könnte.
Könnte man das nicht mit Compiler Direktiven lösen? Damit meine ich nicht das man jede Funktion an/aus schalten können soll, sondern vielmehr das bestimmte Extensions oder herstellerspezifische Funktionen deaktiviert werden können. Habe z.b. noch nie irgendwelche sgi oder mesa Funktionen benutzt. Vielleicht wäre das für ein zukünftiges Release eine brauchbare Erweiterung.
Gruß
damadmax
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
Die Idee kam mir neulich auch schon beim Lesen dieses Threads. Am schönsten wäre es ja, wenn der Loader nur die Funktionen laden würde, die wirklich im Code genutzt werden. Aber wie man das halbwegs sinnvoll (sprich effektiv, simpel und bedienungsfreundlich) in Delphi realisieren könnte, darauf habe ich leider keine Antwort - wenn es denn überhaupt geht.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Nein, da das eine Sache des Compilers ist, kann man nicht nur die Funktionen einkompilieren, die gebraucht werden. Deshalb muss man das tatsächlich entweder per Compilerdirektive machen oder eben manuell in der Final alles rauslöschen, was man nicht braucht.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
Genau das ist das Problem. Allerdings kann der Compiler ja auch von sich aus unbenutzte Codestücke wegoptimieren, auch wenn man das wohl kaum im Header so realisieren kann.
Man könnte zwar die Methode wählen, dass man für jeden DLL-Call eine eigene Headerprozedur macht, die bei not Assigned Pointer erst mal selbigen lädt. Die Leute, die auf Speed aus sind, sind damit dann wahrscheinlich weniger glücklich, dafür werden wirklich nur die notwendigen Calls und deren Ladefunktion kompiliert, die anderen erachtet der Compiler als unnötig und kompiliert sie nicht (keine Breakpoints).
Der Spaß an der Sache ist ja aber, durch die zusätzlichen Speicheradressen und durch die Gegend callen kann es bei Projekten, die viele Calls brauchen, wieder größer werden.
Eine andere Idee war, man könnte vielleicht einen eigenen Header-Compiler bzw. Codegenerator dem Delphi-Compiler vorschalten... wäre dann allerdings wirklich die Minimalistenversion.
Und ob sich jemand diesen enormen Aufwand macht, wenn es mit den Compilerflags auch geht (oder mit löschen/kopieren ), ist schon fragwürdig.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Habs mal ins Feedback verschoben.
Der Kompiler kann da schon was machen. Auch so wie die Unit jetzt ist. Man darf sich nur auf keine Funktionen beziehen. Also auch nicht indirekt. Sobald man ActivateRenderingContext aufruft bezieht man sich aber indirekt auf ALLE Funktionen. Denn dort werden alle Extension geladen. Man kann dies zwar mit einem Parameter unterbinden aber der Kompiler hat trotzdem schon einen indirekten Bezug. Wenn man den RC manuell bindet ist die Echse klein. Man muss dann aber mit ReadImplementationProperties überprüfen welche Extensions vorhanden sind und mit Read_Extensionname einzelne Extension einlesen. Den Kern muss mit ReadOpenGLCore eingelesen werde. Dann kann der Kompiler alle nicht benötigten Texte, Funktionsvariablen entfernen. Alternativ reicht es auch in ActivateRenderingContext die Funktion ReadExtensions auszukommentieren und nur noch die Extensions selber zu laden. Allerdings ist das trotzdem etwas umständlich.
Prinzipiell hast du (damadmax) damit durchaus recht. Die meiste Funktionalität/Extensions wird zu 95% nicht benutzt. Und das verbraucht Platz und Rechenleistung bein Startet.
- Ein andere positiver Effekt davon wäre, dass auch nicht mehr so viele Funktionen geladen werden würden. Was in der Hinsicht auch schon eine Arbeitsersparnis wäre und damit den Code beschleunigen würde.
- Außerdem würde es das Thema Extensions sensibilisieren. Denn ich denke es kommt durchaus schon mal vor, dass man Konstanten und Funktionen von Extensions benutzt bei denen man nicht überprüft hat ob diese überhaupt unterstützt werden. Und wenn man jetzt Extensions erst aktivieren müsste, dann fällt es vermutlich auf, dass man diese normal auf Vorhandensein überprüfen muss.
Aber ich wäre nicht ich, wenn mir nicht auch negatives einfallen würde.
- Es handelt sich dabei um eine Verhaltensänderung des Headers und das führt dazu, dass beim erstens Updaten auf den Header die meistens Programme sich nicht mehr übersetzen ließen. Von Hause aus alles aktivieren würde die Arbeit irgendwie überflüssig machen. Denn wer würde es schon deaktivieren und sich selber arbeit verschaffen.
- So schön es dann wäre die einzelnen Extension aktivieren zu können wird es auch zu einem Muss. Wenn man nicht mehr dran denkt, dass man es machen muss, dann könnte man sich darüber wundern warum die Extension nicht unterstützt wird. Auch das Raussuchen der Extensions könnte dann schnell zu einer echt nervigen Qual werden. Zu mal auch jedes Projekt unterschiedlich ist und man so direkt im Header editieren würde.
PS: GL_SGIS_generate_mipmap ist eine affengeile Extension. Aber seit OpenGL 1.4 befindet sie sich auch im Kern.
Zitat:
Man könnte zwar die Methode wählen, dass man für jeden DLL-Call eine eigene Headerprozedur macht, die bei not Assigned Pointer erst mal selbigen lädt.
Da gibts von mir ein ganz klares nein!! Das war in der .NET Variante schon so ähnlich eingebaut und die war noch größer als der aktuelle Header. Außerdem kam es dadurch innerhalb des Headers zu OpenGL Fehlern. Und mal ganz davon abgesehen, dass das Pflegen des Header eine Sauarbeit war. Weswegen es ja auch rausgeflogen ist.
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
Lossy eX hat geschrieben:
Zitat:
Man könnte zwar die Methode wählen, dass man für jeden DLL-Call eine eigene Headerprozedur macht, die bei not Assigned Pointer erst mal selbigen lädt.
Da gibts von mir ein ganz klares nein!! Das war in der .NET Variante schon so ähnlich eingebaut und die war noch größer als der aktuelle Header. Außerdem kam es dadurch innerhalb des Headers zu OpenGL Fehlern. Und mal ganz davon abgesehen, dass das Pflegen des Header eine Sauarbeit war. Weswegen es ja auch rausgeflogen ist.
Das mit der Größe hab ich ja schon in meinem Beitrag vermutet, daher der Konjunktiv. Und wenn OpenGL/der Treiber nicht mitspielt, kann man die Idee gleich ganz schnell vergessen; und dass es ne Riesenarbeit wäre, wollte ich eben auch schon andeuten.
Wo wir schon dabei sind; auch mal ein Danke von mir an das Team, das einen so guten, umfassenden und aktuellen Header fabriziert!
Und ein Danke für die interessanten Infos drüber an Lossy.
Registriert: Mi Mär 09, 2005 15:54 Beiträge: 372 Wohnort: München
Programmiersprache: Delphi, C#, FPC
Ich finde die Idee mit den Comiler-Direktiven aber wirklich nicht schlecht. Man muss ja nicht direkt jede Funktion einzeln per {$IFDEF} abfragen, aber man könnte doch sicherlich die einzelnen Versionen als Compiler-Direktive lösen. Ungefähr so:
Code:
{$DEFINE GL10}
{$DEFINE GL11}
...
{$DEFINE GL20}
Ich weiß nicht, ob die einzelnen Deklarationen bereits nach OGL-Version sortiert sind, aber wenn, dann könnte man doch sicherlich ganze Blöcke damit per {$IFDEF GL20} rausschmeißen. Wenn man z.B. nur eine Anwendung erstellt, die nur OpenGL 1.3 benutzt, kann man dann ja einfach die GL15 und die GL20 - Defines auskommentieren. Was dabei auch noch praktisch wäre ist, dass man sofort sieht, welche OpenGL-Version man für sein Programm als Minimum vorraussetzten muss.
Doch bevor ich es vergesse:
Vielen dank an das ganze DGL-Header-Team für den wirklich sehr guten Header (wenn das Team wirklich nur aus Lossy bestehen sollte, dann natürlich danke dir, Lossy )
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ja, wo wir gerade bei den Lobsängen sind: Dieser header ist wirklich seeeehr gut und ich hoffe Lossy, dass du das auch weiterhin (vorallem mit dem Aufkommenden OpenGL3.0) weiterhin so gut betreust
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 Wohnort: Berlin
Programmiersprache: Go, C/C++
Wenn du FPC nutzt dann einfach an aller erster Zeile {$SMART ON} rein und in der fpc.cfg das Smartlinking rein.
Dauert dann länger mit dem compilieren aber dafür fallen alle nicht gebrauchten Konstanten raus.
Der Header ist leider ungünstig geschrieben, da alle funktionen in einer funktion geladen werden und damit immer benötigt werden.
Wenn man für SMART ein guten Header haben will, dann sollten die funktionen über macros geladen werden, damit kann SMART alle funktionen aus den Makros streichen, die ned gebraucht werden.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Hört auf zu schleimen. Das wird eine Entscheidung auch nicht beeinflussen. Aber ich sach mal danke. Auch im Namen aller die jemals daran gewirkt haben. Es ist zwar richtig, dass ich mich derzeit alleine drum kümmere aber den Anfang haben Viele gemacht und derzeit ist es nur neue Extension einpflegen.
Makros: Das Prinzip ist richtig. Es ist so der Kompiler kann aktuell nichts daran ändern, da immer die Methoden in einer Beziehung stehen. Aber die Makros fallen raus. Alleine schon weil mindestens ich noch in Delphi entwickel und das kann keine Makros.
Die Conditional Defines. Sind zwar auch ganz nett aber alleine schon der Kern ist ein riesen Batzen. Da weiß ich nicht ob das so viel bringt. Zu mal vom Kern ja auch nur maximal 5% der Methoden sinnvoll genutzt werden. Das Beste wäre, wenn man es wirklich so macht, dass nur einzelne Methoden geladen werden. Und zwar nicht per CD sondern wie in C++ eher üblich. Also der Header stellt die Methode zum Laden zur Verfügung und ein CD welches das Laden verhindert und dann kann man sich selber aussuchen welche Methodenpointer man braucht und welche nicht.
Hacken an der Sache. Das ist fummelarbeit das pro Anwendung zu machen. Aber dann ist der Header auch nur so groß wie nötig. Denn einzelne Kernversionen auszuschließen bringt aus meiner Sicht wohl eher auch nicht so viel. Denn ich persönlich benutze meistens immer irgendwas aus allen Kernen. Außer 2.0+. Also zu mindest wäre das so meine Idee. Aber die erste Idee ist nicht immer die Beste.
Bliebe dann noch die möglichkeit, das man eine art Pre-Compiler schreibt, die den Header automatisch anpasst ... die Idee kam mir damals bei den Indy komponenten, die ja auch ne ganze menge balast mit sich schleppen ( wer will schon in einem prog sämtliche netzwerkprotokolle als server und client usw einbinden?!)
Wenn man das also allgemein hält könnte man wohl nochmal ne ganze menge an speicher sparen, ist dann nur die frage ob man das wirklich noch braucht. auch so ist der code meist das kleinste an jedem prog ... die ganzen media daten wiegen da viel schwerer.
Ich schlage vor das hier als Gemeinschaftsprojekt zu starten, da es ja schon einige gibt die sich ähnliche gedanken gemacht haben wie ich.
um das jedoch realisieren zu können müssten sämtliche includes nen bestimmten standart einhalten, damit es nicht stört, wenn manche module nicht mehr dabei sind.
Bitte um Rückmeldungen wer daran interssiert wäre!
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also zu viele verschiedene Möglichkeiten möchte ich da ehrlich nicht mischen. Denn meine Meinung nach wird der Großteil das sowieso nicht benutzen. Zu mal solche Sachen den Verwaltungsaufwand des Header erhöhen. Allerdings selbst, wenn du nur einzelne Erweiterungen komplett aktivierst ist der Overhead noch ziemlich groß. Allen voran die Kernversionen von OpenGL enthalten eine Vielzahl an Funktionen. Und genau davon werden gerade nur ein paar Funktionen wirklich benutzt. Viele der exotischen Erweiterungen bestehen nur aus 1-2 Methoden oder nur irgendwelchen Konstanten. Und die Konstanten belegen nur Platz im Code. In der Echse werden diese so direkt eingesetzt. Von daher denke ich, dass ein Header der nur die Variablen und die Typen definiert ist da schon das Sparsamste was man machen kann. Alles andere würde nur den Schein von Sparsamkeit erwecken.
Was die Änderungen angeht hatte ich schon mal eine BETA Version gemacht. Das hatte ich zwar noch mal ein bisschen überarbeitet allerdings noch nicht öffentlich gemacht. Wollte da nur noch auf deine Änderung mit dem Funktionsergebnis warten.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 Wohnort: Berlin
Programmiersprache: Go, C/C++
Gute und große Bibliotheken lösen das über Compiler Direktiven, indem man einfach Module fest legt.
wxWidget ist da ein sehr gutes Beispiel, dort sind alle erweiterungen in einer Zentralen Header Datei definiert und man kann bei belieben das define auf 1(an) oder 0(aus) setzen. Damit verkürzt sich die Compilerzeit extrem, da er über den Code erst garnicht rüber geht und somit nicht optimiert werden muss.
Um das ganze mal ein bischen fest zu machen, hier mal ein Beispiel aus mein Projekt https://svn.linuxprofessionals.org/filedetails.php?repname=karmarama&path=%2Ftrunk%2Finclude%2Fkarmarama.hpp.
Diese Defines kann man im Fall von dglOpengl.pas auch am Anfang, der Unit, packen.
Die Funktionen sind ja schon in Gruppen zusammen gefasst und durch Ladefunktionen gebündelt.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.