Warum ist "Text" so derart langsam?

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

Hubsi

Betreff: Warum ist "Text" so derart langsam?

BeitragFr, Sep 06, 2013 22:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Hai beisammen.

Das der Befehl Text (B3D) nicht gerade den Turbo drin hat ist mir bewusst, was mich interessieren würde ist wie er intern arbeitet, bzw. was ihn so lahm macht oder hängt das auch mit der Hardware zusammen? Die Frage kam mir gerade eben in den Sinn als ich die Botanzahl in meinem aktuellen Projekt auf reale Werte eingestellt habe und jeder dieser Bots einige Werte die ich zum debuggen benötigt habe mit Text auf den Bildschirm pinselte. Geht schnell und einfach und zum debuggen ist ja egal, dachte ich. Nur das plötzliche Geruckel hat mir dann nicht mehr gefallen Mr. Green
Ich habe nicht vor Text zu benutzen, mich interessiert wie gesagt nur was es denn so überaus langsam sein lässt?
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

Kruemelator

BeitragFr, Sep 06, 2013 23:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Genau wissen tue ich es nicht, aber ich nehme an das der CPU genutzt wird und nicht die Grafikkarte.

DAK

BeitragSa, Sep 07, 2013 11:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Was das Problem mit dem Text-Befehl ist, ist dass er quasi jeden Buchstaben als Bild zeichnet. Wenn man dann einen Text mit 500-1000 Zeichen hat, dann muss er für jedes Zeichen das Bild dazu aufrufen und zeichnen. Mit der Menge an gezeichneten Bildern (auch ohne dem Text-Befehl, sondern mit normalen Bildern) braucht's hald schon viel Rechenzeit.

Um das Problem zu umgehen gibt es ein paar Optimierungsmöglichkeiten:
1) Nur Text zeichnen, der auf dem Bildschirm landet, da ansonsten diese Aufrufe immer noch gemacht werden können, und er erst beim Zeichnen jedes Buchstaben überprüfen kann, ob der am Bildschirm ist oder nicht, und so weggelassen werden kann.
2) Text vorrendern. Das funktioniert nur gut, wenn der Text sich nicht oft ändert. Da rendert man den Text erst auf einen Imagebuffer, und zeichnet den dann als Bild. Auf die Art zeichnest du zwar immer noch die gleiche Menge Text auf den Schirm, aber das Programm muss nicht mehr jeden Buchstaben einzeln zeichnen, was einen deutlichen Geschwindigkeitsanstieg gibt. Wenn sich nur ein Teil des Textes ändert, dann kann man den statischen Teil vorrendern, und den Dynamischen dann mit (ggF. mehreren) Text einfügen.

Dazu noch: Zwei mal Text mit je 500 Zeichen aufrufen ist annähernd gleich schnell, wie ein mal Text mit 1000 Zeichen.

Edit:
@Kruemelator: in B3D wird für die 2D-Befehle (wie z.B. Text, DrawImage, Rect, o.Ä.) immer nur die CPU und nicht die Grafikkarte verwendet. Grafikkartenunterstützung kam erst wirklich bei den 3D-Befehlen von B3D dazu. Deswegen gibt es ja auch die Draw3D-Library, die die 2D-Befehle mit 3D "nachbaut", wodurch Grafikkartenunterstützung dabei ist, und Effekte wie Alpha oder Echtzeitdrehung drinnen sind.
Gewinner der 6. und der 68. BlitzCodeCompo

Hubsi

BeitragSa, Sep 07, 2013 11:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Da wird mir jetzt einiges klarer. Ich verwende bmp-Fonts für die normalen Textausgaben (also die im Spiel bleiben werden) und habe mir beschämenderweise noch nie Gedanken dazu gemacht wie viele Einzelbilder ich da eigentlich zeichnen muß. Durch die überdurchschnittliche Ausgabe an Debugwerten ist mir das jetzt erst mal aufgefallen. Vielen Dank den Tip Very Happy
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

The Shark

BeitragSa, Sep 07, 2013 22:22
Antworten mit Zitat
Benutzer-Profile anzeigen
DAK hat Folgendes geschrieben:
Was das Problem mit dem Text-Befehl ist, ist dass er quasi jeden Buchstaben als Bild zeichnet. Wenn man dann einen Text mit 500-1000 Zeichen hat, dann muss er für jedes Zeichen das Bild dazu aufrufen und zeichnen. Mit der Menge an gezeichneten Bildern (auch ohne dem Text-Befehl, sondern mit normalen Bildern) braucht's hald schon viel Rechenzeit.

Es ist sogar noch ein bisschen schlimmer. Der Text durch die Fontengine (des Betriebsystems?) gerendert. Also Für jeden Text aus den Informationen über jeden Buchstaben (verschiedenste Abstände, Größen usw. und dem Aussehen der Buchstaben in Vektorgrafik) den Text als Pixelgrafik zu rendern.

Alleine der stupide Ansatz, jedes Zeichen des Fonts in ein bild vorzurendern und den Text selber aus den Bildern anzuzeigen bringt bei kurzen Texten schon einen ordentlichen Performanceboost.

Um das Vorrendern ganzer Texte, die sich nicht ändern kommt man aber früher oder später nicht rum ^^

DAK

BeitragSa, Sep 07, 2013 22:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenigstens geht das Vorrendern in B3D wirklich einfach. Einfach mal den Buffer auf Imagebuffer setzen und das wars schon. Das braucht in BMax schon ein wenig mehr (ist auch dort nicht dramatisch, aber trotzdem).
Gewinner der 6. und der 68. BlitzCodeCompo

maximilian

BeitragSo, Sep 08, 2013 1:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem wurde bis jetzt noch nicht in diesem Thread erwähnt.

Text benutzt die von Windows bereitgestellten Funktionen zum Zeichnen von TrueType-Fonts (GDI). Alle anderen 2D-Zeichenfunktionen von BB nutzen DirectX bzw. DirectDraw. Wenn man das z.B. vergleicht mit der Bitmap-Fontengine von BlitzMax wird man feststellen, dass es dort keinen solchen Performanceeinbruch gibt, da DrawText genauso die ausgewählte Schnittstelle verwendet, wie alle anderen Funktionen auch.

Wodurch genau der Performanceeinbruch kommt, weiß ich leider nicht, da müsste man mal jemanden mit entsprechender DirectDraw-Expertise befragen. Meine Vermutung wäre aber, dass das Surface gelockt werden muss. Deswegen vielleicht mal probieren, vor dem Aufrufen von mehreren sukzessiven Text-Befehlen LockBuffer aufzurufen? Könnte schneller sein...

@DAK: Da liegst du falsch. DirectDraw (und somit alle 2D-Zeichenfunktionen von Blitz) wird genauso von der Hardware beschleunigt wie Direct3D auch.
Variety is the spice of life. One day ignore people, next day annoy them.

The Shark

BeitragSo, Sep 08, 2013 2:24
Antworten mit Zitat
Benutzer-Profile anzeigen
maximilian hat Folgendes geschrieben:
Wodurch genau der Performanceeinbruch kommt, weiß ich leider nicht, da müsste man mal jemanden mit entsprechender DirectDraw-Expertise befragen. Meine Vermutung wäre aber, dass das Surface gelockt werden muss. Deswegen vielleicht mal probieren, vor dem Aufrufen von mehreren sukzessiven Text-Befehlen LockBuffer aufzurufen? Könnte schneller sein...

Ich denke alleine schon das pure Rendern von großen mengen Text bei 60fps kostet einiges an Leistung.
maximilian hat Folgendes geschrieben:

@DAK: Da liegst du falsch. DirectDraw (und somit alle 2D-Zeichenfunktionen von Blitz) wird genauso von der Hardware beschleunigt wie Direct3D auch.

Naja, nicht wirklich. Direct Draw kann zwar theoretisch Hardwarebeschleunigt werden, moderne Grafikkarten sind aber nichtmehr wirklich darauf ausgelegt (Stichwort Blitting), weshalb große Teile vom Prozessor emuliert werden müssen.

maximilian

BeitragSo, Sep 08, 2013 21:29
Antworten mit Zitat
Benutzer-Profile anzeigen
The Shark hat Folgendes geschrieben:
maximilian hat Folgendes geschrieben:
Wodurch genau der Performanceeinbruch kommt, weiß ich leider nicht, da müsste man mal jemanden mit entsprechender DirectDraw-Expertise befragen. Meine Vermutung wäre aber, dass das Surface gelockt werden muss. Deswegen vielleicht mal probieren, vor dem Aufrufen von mehreren sukzessiven Text-Befehlen LockBuffer aufzurufen? Könnte schneller sein...

Ich denke alleine schon das pure Rendern von großen mengen Text bei 60fps kostet einiges an Leistung.
maximilian hat Folgendes geschrieben:

@DAK: Da liegst du falsch. DirectDraw (und somit alle 2D-Zeichenfunktionen von Blitz) wird genauso von der Hardware beschleunigt wie Direct3D auch.

Naja, nicht wirklich. Direct Draw kann zwar theoretisch Hardwarebeschleunigt werden, moderne Grafikkarten sind aber nichtmehr wirklich darauf ausgelegt (Stichwort Blitting), weshalb große Teile vom Prozessor emuliert werden müssen.


Nunja, 99% aller Computerprogramme heutzutage sind irgendwie darauf angewiesen, Text anzuzeigen. Dementsprechend effizient sind auch die bereitgestellten Routinen... So viel Text, dass GPU oder CPU ernsthaft ins Schwitzen geraten, kannst du auf einem handelsüblichen Bildschirm überhaupt nicht anzeigen.

Wie kommst du darauf, dass DirectDraw heutzutage über die CPU läuft? Diese These halte ich für äußerst abenteuerlich. Es widerspricht jeglicher Logik, solche stupiden Aufgaben durch eine CPU rechnen zu lassen in Zeiten von voll programmieren GPUs, die genau für solche Aufgaben konzipiert wurden.
Variety is the spice of life. One day ignore people, next day annoy them.

DAK

BeitragMo, Sep 09, 2013 0:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Also erstmal dazu, wie andere Systeme viel Text darstellen: (Das ist jetzt direkt aus Java-Swing, Android und den Standard-Windows-GUI-Oberflächen, nehme aber an, dass es von fast allen anderen Systemen auch so gemacht wird)
Die Oberfläche wird ein mal gerendert und als Bild abgespeichert. Dann wird, solange es sich nicht verändert, der Teil im Grafikbuffer nicht gelöscht und muss somit nicht mehr neu gezeichnet werden (in BB würde das heißen, wenn sich nichts verändert, CLS und sämtlichen Grafikausgaben wegzulassen).
Wenn sich etwas verschiebt (z.B. Scrollbox, Fenster verschieben), dann wird aus dem vorgerenderten Bild gezeichnet.
Nur wenn sich der Bildinhalt wirklich ändert, wird neu gerendert.

Mit dem System kannst du den ganzen Bildschirm voller Text haben, und verbrauchst quasi gar keine Rechenzeit. Nur wenn man darauf besteht, jedes Pixel in jedem Schleifendurchlauf völlig unsinnigerweise neuzurendern, dann frisst es Leistung.

@maximilian: Probiers doch aus. Bau dir ein Testprogramm, dass eine Million DrawTexts pro Frame macht, lass es ohne Framelimiter laufen und schau dann (mittels Tools wie GPU-Z), wie viel Auslastung auf der Grafikkarte liegt, und wie viel auf der CPU. Die Graka wird ein paar % haben, weil jeder Grafikbefehl irgendwann durch die Graka geht (wenn auch nicht durch sie beschleunigt), aber die CPU wird voll sein.

@Effizienz von Textdarstellungsroutinen: Ja, DirectDraw ist sehr effizient und optimiert ... für Geräte von vor 13 Jahren! Die jetzte Verson von Dx7 ist meines Wissens am 14. 9. 2000 raus gekommen, zu einer Zeit, wo die meisten Computer gar nicht sowas wie Grafikbeschleunigung gehabt haben, die über mehr als einen Blitter hinausgegangen sind.
Wo der Dx7-Support unter Dx9 noch recht gut war, ist er jetzt unter Dx11 echt am Ende. Bei der Implementation der Dx7-Emulation unter Dx11 war ihnen die Performanz absolut egal. Da ging es nur darum, dass es läuft, und auch das war ihnen nicht ein allzugroßes Anliegen. Sieht man gut daran, dass B3D-Spiele auf einem alten XP-Rechner mit einem Pentium 4 teils schneller laufen, als auf einem Windows 8 mit einem i5.
Gewinner der 6. und der 68. BlitzCodeCompo
  • Zuletzt bearbeitet von DAK am Mo, Sep 09, 2013 0:17, insgesamt einmal bearbeitet

Chester

BeitragMo, Sep 09, 2013 0:12
Antworten mit Zitat
Benutzer-Profile anzeigen
maximilian hat Folgendes geschrieben:
Wie kommst du darauf, dass DirectDraw heutzutage über die CPU läuft? Diese These halte ich für äußerst abenteuerlich.


Ich weiß zwar jetzt nicht, wie DirectDraw intern funktioniert, aber die DirectDraw API selbst wurde 2010 schon rausgeschmissen und in Direct3D integriert bzw später mit dem Erscheinen von DirectX10 durch Direct2D abgelöst. Insofern halte ich es für möglich, dass neuere Chips mit dem alten Design nichts anfangen können.

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group