"Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?
Verfasst: Sa 8. Jul 2023, 18:45
Hallo!
Ich habe da eine vielleicht etwas ungewöhnlich Idee.
Es ist vielleicht eher ein Experiment als eine wirklich praktisch sinnvolle Sache - aber das muss man noch überlegen.
Und zwar soll es hier einmal um die Idee gehen, soetwas wie Sprites nicht durch Kopieren von einem Speicherbereich in den anderen letztlich auf den Bildschirm zu bringen, sondern die Bilddaten direkt in ausführbaren Code zu verwandeln, wodurch das einlesen der Daten entfällt. Zudem entfallen jegliche Sprünge innerhalb einer Kopier-Routine, wie auch Vergleiche bzw. Prüfungen, etwa bei Transparenz.
Natürlich würden die Daten somit deutlich aufgebläht.
Wenn ein Pixel einer solchen Grafik nunmehr als Code z.B. durch "mov [di+1234], al" repräsentiert wird, d.h. mit dem Maschinencode " 88 85 d2 04 "dann haben wir hier den 4-fachen Speicherplatzbedarf.
Das ganze relativiert sich allerdings, wenn in der Grafik z.B. vier Pixel der gleichen Farbe nebeneinanderliegen, diese kann man, wenn EAX vorher entsprechend belegt wurde, durch "db 66h; mov [di+1234], ax", d.h. "66 89 85 d2 04" erledigen, somit nur noch der 5/4-fache Speicherplatzbedarf.
Der "Trick" bei der ganzen Angelegenheit wäre, die Grafiken in ihre einzelnen Farben aufzudröseln, und jeweils das AL Register, oder bei 2 oder 4 nebeneinander vorkommenden gleichen Pixeln das AX- resp. EAX-Register entsprechend vorzubereiten.
Als nächstes würden dann entsprechende Pixel per mov ... al, ax, oder eax geschrieben.
Auf diese Weise kann man transparente Bereiche dann auch einfach auslassen.
Ich bin mir gerade nicht sicher, ob man diesen so generierten Code als Daten auf den Heap laden und dort ausführen kann.
Also, das ganze soll eher als Experiment betrachtet werden, da man abwägen muss, ob die vierfache Datengröße wirklich einen überhaupt existierenden Geschwindigkeitsvorteil rechtfertigt.
Möglicherweise bringt diese Vorgehensweise aber auch weitere Ideen mit sich.
Noch etwas zur Positionierung im Puffer oder auf dem Bildschirm: Der generierte Code würde eine feste X-Breite des Puffers oder des Bildschirmspeichers voraussetzen. Dann kann durch Übergabe von DI die x-y Position der linken oberen Ecke festgelegt werden. Hat man etwa eine Breite des Puffers von 320 Pixeln, dann beginnt die erste Zeile der darzustellenden Grafik bei DI+0, die nächste bei DI+320 etc. Ist eigentlich selbsterklärend. Clipping geht so leider erstmal nicht.
Noch zu klären wäre: Sind Speicherzugriffe über Register + Offset wirklich so schnell wie nur über Register?
Und etwas zu mir: Mein bevorzugter Grafikmodus ist MCGA 320x200. Der hat den Nachteil dass er nur eine Seite hat und dass man deshalb im Speicher puffern muss und dann in den Grafikspeicher kopieren. Der echte VGA-Modus ist mir bislang zu kompliziert zu programmieren.
Ich habe da eine vielleicht etwas ungewöhnlich Idee.
Es ist vielleicht eher ein Experiment als eine wirklich praktisch sinnvolle Sache - aber das muss man noch überlegen.
Und zwar soll es hier einmal um die Idee gehen, soetwas wie Sprites nicht durch Kopieren von einem Speicherbereich in den anderen letztlich auf den Bildschirm zu bringen, sondern die Bilddaten direkt in ausführbaren Code zu verwandeln, wodurch das einlesen der Daten entfällt. Zudem entfallen jegliche Sprünge innerhalb einer Kopier-Routine, wie auch Vergleiche bzw. Prüfungen, etwa bei Transparenz.
Natürlich würden die Daten somit deutlich aufgebläht.
Wenn ein Pixel einer solchen Grafik nunmehr als Code z.B. durch "mov [di+1234], al" repräsentiert wird, d.h. mit dem Maschinencode " 88 85 d2 04 "dann haben wir hier den 4-fachen Speicherplatzbedarf.
Das ganze relativiert sich allerdings, wenn in der Grafik z.B. vier Pixel der gleichen Farbe nebeneinanderliegen, diese kann man, wenn EAX vorher entsprechend belegt wurde, durch "db 66h; mov [di+1234], ax", d.h. "66 89 85 d2 04" erledigen, somit nur noch der 5/4-fache Speicherplatzbedarf.
Der "Trick" bei der ganzen Angelegenheit wäre, die Grafiken in ihre einzelnen Farben aufzudröseln, und jeweils das AL Register, oder bei 2 oder 4 nebeneinander vorkommenden gleichen Pixeln das AX- resp. EAX-Register entsprechend vorzubereiten.
Als nächstes würden dann entsprechende Pixel per mov ... al, ax, oder eax geschrieben.
Auf diese Weise kann man transparente Bereiche dann auch einfach auslassen.
Ich bin mir gerade nicht sicher, ob man diesen so generierten Code als Daten auf den Heap laden und dort ausführen kann.
Also, das ganze soll eher als Experiment betrachtet werden, da man abwägen muss, ob die vierfache Datengröße wirklich einen überhaupt existierenden Geschwindigkeitsvorteil rechtfertigt.
Möglicherweise bringt diese Vorgehensweise aber auch weitere Ideen mit sich.
Noch etwas zur Positionierung im Puffer oder auf dem Bildschirm: Der generierte Code würde eine feste X-Breite des Puffers oder des Bildschirmspeichers voraussetzen. Dann kann durch Übergabe von DI die x-y Position der linken oberen Ecke festgelegt werden. Hat man etwa eine Breite des Puffers von 320 Pixeln, dann beginnt die erste Zeile der darzustellenden Grafik bei DI+0, die nächste bei DI+320 etc. Ist eigentlich selbsterklärend. Clipping geht so leider erstmal nicht.
Noch zu klären wäre: Sind Speicherzugriffe über Register + Offset wirklich so schnell wie nur über Register?
Und etwas zu mir: Mein bevorzugter Grafikmodus ist MCGA 320x200. Der hat den Nachteil dass er nur eine Seite hat und dass man deshalb im Speicher puffern muss und dann in den Grafikspeicher kopieren. Der echte VGA-Modus ist mir bislang zu kompliziert zu programmieren.