Lockere Optimierung von Gdiplus-Code
-
Grüße!
Auch wenn ich nebenbei meinen Direct2D-Branch zusammenfrickle, habe ich mal mein Programm mit Gdiplus durch den Profiler gejagt. Hier findet ihr einen Screenshot des Ergebnisses: http://postimage.org/image/5izqrosv7/.
Nun ist ja klar, um welche Funktionen ich mich kümmern sollte, um das Neuzeichnen zu beschleunigen:
_GdipDrawString@28 88 88 20,51 20,51
Hier ist natürlich klar, wenn sich Strings im Inhalt nicht ändern, kann ich sie in einer Bitmap puffern._GdipDrawLineI@24 87 87 20,28 20,28
Das hier ist mir echt ein Rätsel. Einzel-Calls, um Linien zu zeichnen, verwende ich nur für Grid-Linien in Koordinatensystemen zu zeichnen. Das sind so 16 Stück pro Datenkurve. Außerdem sind die Dinger axis-aligned. Kann es sein, dass der Aufruf-Overhead hier das teure ist? Bin am Überlegen, ob ich das für Gdiplus irgendwie batchen kann.Unbekannt 375 69 87,41 16,08
Das ist der Boilerplate-Code zwischen GetMessage und CView::OnDraw ... Verstehe nicht, wie das so vieleinklusiveexklusive samples sein können. Mag das ein Erase-Background sein, das ich nicht vernünftig unterbunden habe? Leider zeigt mir der Performance-Explorer hier keine weiteren Details, außer dass von hier OnDraw aufgerufen wird._GdipDrawLines@16 56 56 13,05 13,05
Hier werden die Datenkurven gezeichnet, da kann ich wohl nicht mehr so viel dran drehen und es ist ja jetzt schon schneller, als die Gitterlinien zu zeichnenFür Ideen und Anregungen wäre ich sehr dankbar!
Viele Grüße,
Deci
-
Moah, man kann mit Gdiplus ja nichtmal konkurrent in Worker-Threads in unabhängige Offscreen-Puffer rendern. Diese API ist so dermaßen verhunzt...
Immerhin kann man mit FillRectangle schnelle axis-aligned Linien emulieren...Ich denke darüber nach, in meinem d2d-port einen threadpool oder mindestens einen Thread einzurichten, der im Hintergrund das Neuzeichnen betreibt, sodass der GUI-Thread nur noch aus dem Back-Buffer blitten braucht... klingt das nach einer vernünftigen Idee?
-
Decimad schrieb:
Diese API ist so dermaßen verhunzt...
Es gibt nur eine Sache die an dieser API verhunzt ist, und das sind die DrawImage(...) & Co. Funktionen - der Rest ist mein Erfahrung nach schnell und zuverlässig.
Dein Test ist ohne weite Angaben und Code für Außenstehende ziemlich nutzlos. Was zum Beispiel ist der unterscheid zwischen inklusiven und exklusiven Samples? (kernel<>user land?)
-
Nun, mit exklusiven und inklusiven Samples beziehe ich mich auf die Metrik des Sample-basierten Profilings vom Visual-Studio-Profiler.
Exklusiv = Samples nur in diesem Funktionskörper
Inklusiv = Samples in diesem Funktionskörper + allen Aufrufen davonEdit: Und ich finde es eine Schwäche der API, dass man im selben Prozess nicht innerhalb von mehreren Threads gleichzeitig in unterschiedliche Memory-Bitmaps zeichnen kann.
-
Decimad schrieb:
Moah, man kann mit Gdiplus ja nichtmal konkurrent in Worker-Threads in unabhängige Offscreen-Puffer rendern. Diese API ist so dermaßen verhunzt...
Weil GDI+ dann abkackt oder weil das Ding intern wo nen Lock nimmt und dadurch einfach nix parallel läuft?
-
Letzteres, globale mutexe...
also nicht so total global, sonder so global wie eben globale Variablen oder statics außerhalbt von tls.. Prozessweit wollte ich sagen.
-
GDI und GDI+ sind deprecated. Gibt es einen besonderen Grund, wieso du den Code optimieren musst? Imo wäre es wesentlich sinnvoller, stattdessen in der Direct2D Branch nicht zu frickeln...
-
Naja, ich bin unzufrieden mit der Framerate/CPU-Auslastung und die D2D-Sache dauert noch etwas... Wenn ich also das Gdiplus-Zeugs mit kleineren Eingriffen tauglicher bekäme, kann ich flexibler mit meiner Zeit umgehen.