Gesucht: Der schnellste Weg ein Bild zu pixeln
Übersicht

![]() |
MercedBetreff: Gesucht: Der schnellste Weg ein Bild zu pixeln |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich bin momentan dabei einige Routinen zu optimieren um einige Sachen auch auf lahmen Rechnern besser zum laufen zu bringen. Dabei habe ich eine eigene Bild-Laderoutine. Ich lade die Bilddaten (RGB) als Block in eine Bank und pixle sie dann einzeln in ein Image.
So sieht das Pixeln aus: Code: [AUSKLAPPEN] LockBuffer ImageBuffer(img) z = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, ((256*256*256*255)+(256*256*r)+(256*g)+b), ImageBuffer(img) Next Next UnlockBuffer ImageBuffer(img) Die einzelnen Variablen sollten einleuchtend sein, gbr ist die Reihenfolge der Farben in diesen Daten (das Ergebnis stimmt). Die Wurst mit Multiplikationen errechnet den Farbwert. Weiß jemand einen Weg das schneller zu lösen? Auch minimale Beschleunigung (auf schnellen Rechnern nicht meßbar ![]() |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ersetze die Multiplikationen durch ihre Ergebnisse (soweit machbar), spart schon ein paar nanosekunden... | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] WritePixelFast x, y, ((256*256*256*255)+(256*256*r)+(256*g)+b), ImageBuffer(img) Hier würde ich die Multiplikationen manuell ausrechnen und die Werte direkt eintragen. Dann muss das nicht immer extra berechnet werden. |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okay. Das hatte ich zwar schon gemeint, aber danke! Noch mehr Ideen? Kann auch gerne ein anderer Ansatz zum Erstellen des Bildes sein - hauptsache es wird noch etwas schneller.
Ein paar Nanosekunden kann man zwar mit Blitz nicht messen aber auf altersschwachen Systemen werden daraus schnell einige Millisekunden und die sind dann schon spürbar ![]() Der etwas verbesserte Code: Code: [AUSKLAPPEN] LockBuffer ImageBuffer(img) z = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, ((4278190080)+(65536*r)+(256*g)+b), ImageBuffer(img) Next Next UnlockBuffer ImageBuffer(img) |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wieso liest du das Byteweise aus und stöpselst es wieder zusammen... du könntest doch gleich peekint machen(vorsicht Alphakanal berücksichtigen!)
Mit Blitz+ kann man auch direkt auf den Imagebuffer zugreifen was nochmal schneller gehen würde. |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm. Ja, das ist eine gute Idee.
Funktioniert leider nicht, da peekint einen 32-Byte Integer liest, die Datei aber nur 24-Bit Farben enthält. Außerdem ist die Reihenfolge der Daten nicht RGB, sondern GBR, womit das endgültig flachfällt. Danke trotzdem für den Tipp. Die Blitz+ Lösung wird wohl nicht funktionieren, da ich Blitz3D verwende. |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
RallimenSieger des 30-EUR-Wettbewerbs |
![]() Antworten mit Zitat ![]() |
---|---|---|
evt. ist es schneller wenn du erst
Code: [AUSKLAPPEN] setbuffer imagebuffer (bild)
lockbuffer und Code: [AUSKLAPPEN] writepixelfast x,y,rgb
ohne angabe des Buffers schreibst muste dann allerdings wieder auf Backbuffer setzten ich mach mal ebend CodeBeispiel: Code: [AUSKLAPPEN] Graphics 800,600,16,1
Delay 100 bild = CreateImage (10,10) timer = MilliSecs() LockBuffer ImageBuffer (bild) For i =0 To 10000000 WritePixelFast 5,5,$FFFFFFFF,ImageBuffer (bild) Next UnlockBuffer ImageBuffer (bild) timer1 = MilliSecs() - timer timer = MilliSecs() SetBuffer ImageBuffer (bild) LockBuffer For i =0 To 10000000 WritePixelFast 5,5,$FFFFFFFF Next UnlockBuffer SetBuffer BackBuffer() timer2 = MilliSecs() - timer Print "Variante 1: "+ timer1 Print "Variante 2: "+ timer2 WaitKey End Variante 1 = 285 Variante 2 = 185 bei mir ist es schneller |
||
[BB2D | BB3D | BB+]
|
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Karamba!
Nach solchen Tweaks such ich ![]() Auf der Schrottmühle an der ich mich gerade versuche läuft Dein Test folgendermassen: Variante 1 = 13832 *lol* Variante 2 = 7400 (ist das älteste was ich gefunden hab: Ein Sellery 400) Das braucht knapp halb soviel Zeit. Leider verpufft der Vorteil sehr stark beim Pixeln mit den Daten. Hier die Daten vom Laden eines 512x512 großen Bildes: Variante 1 = 1668 Variante 2 = 1585 Ist nicht viel aber immerhin hat es dass um etwa 5 % beschleunigt. Danke! Zu den Daten. Die Werte für Breite und Höhe werden vorher bestimmt. Dann folgen nur noch die reinen unkomprimierten 24-Farbdaten: GBRGBRGBR... Hier die aktuell schnellste Variante um daraus wieder ein Bild zu machen: Code: [AUSKLAPPEN] img = CreateImage(tbreite, thohe) SetBuffer ImageBuffer(img) LockBuffer ImageBuffer(img) z = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, ((4278190080)+(65536*r)+(256*g)+b) Next Next UnlockBuffer ImageBuffer(img) SetBuffer BackBuffer() Noch jemand eine gute Idee? |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
joachim_neu |
![]() Antworten mit Zitat ![]() |
---|---|---|
wenn du fertig bist, stell deine routine bitte ins codearchiv!!! sehr gute idee!!! | ||
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de |
![]() |
RallimenSieger des 30-EUR-Wettbewerbs |
![]() Antworten mit Zitat ![]() |
---|---|---|
hab da noch etwas was schneller sein sollte....
habs jetzt aber nicht getestetCode: [AUSKLAPPEN] WritePixelFast x, y, (($ff000000) + (r Shl 16) + (g Shl 8) + b)
|
||
[BB2D | BB3D | BB+]
|
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm. Seeeehr seltsam.
Ich hab den Code mal so mal so laufen lassen. Ergebnis: Die alte Methode mit Multiplikation hatte folgende Werte: 1585, 1613 und 1606 ms Deine mit Shl: (Und ja, die alte Berechnung war nicht mit drin) 1621, 1636 und 1590 ms. Bis auf die 1590 war es mit Shl immer ein bisschen langsamer. Und die 1590 kommen auch nicht an die 1585 ran. Man schließe: Selber rechnen ist in dem Fall sogar schneller als die entsprechende Routine ![]() Ach ja: Hab auch mal beide Hintereinander gehangen (mit einem FreeImage dazwischen nochmal neu aufgebaut). Ergebnis: Unabhängig davon welche Routine ich als zweites verwendet habe - sie war IMMER fast doppelt so schnell wie die erste Berechnung. @joachim Kann ich machen, aber ich glaub nicht dass sie vielen was bringt. Der einzige Grund den ich sehe sowas zu pixeln ist ein eigenes Grafikformat und mal ehrlich: Wieviele hier benutzen ein eigenes? Öhm... *meld* Übrigens ist mir da noch eine Idee gekommen mit der ich in meinem konkreten Fall zwei Fliegen mit einer Klappe schlagen kann. Ich füge dem Format eine RLE-Kompression hinzu. Dadurch spare ich Platz und muss häufig wiederkehrende Farben nicht zig mal hintereinander berechnen. |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
Gib bitte auch den Bankeinladecode!
Btw. bringen diese ganzen Klammern etwas?!Zitat: ((4278190080)+(65536*r)+(256*g)+b)
|
||
MrKeks.net |
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Öhm, die Klammern haben ursprünglich mal für mehr Übersicht gesorgt. Aber die Testwerte liegen mit oder ohne Klammern etwa gleich. Da die Schwankungen (beim gleichen Test) jeweils bis zu 100 ms betragen ist es schwer es in Stein zu meisseln - seltsamerweise ist es aber in 4 von 5 Versuchen MIT Klammern zwischen 13 und 78 ms schneller gewesen (einmal 10 ms langsamer). Bei einem Zeitrahmen von 1500-1700 Millisekunden für den Bildaufbau.
Hier der Code nochmal mit Bankeinladung: (welcher mit ca 500-600 ms zusätzlich zu Buche schlägt auf dem erwähnten Sellery 400) Code: [AUSKLAPPEN] mem = CreateBank(tsize) hasread = ReadBytes(mem,vgf,0,tsize) If hasread <> tsize Then Return 0 img = CreateImage(tbreite, thohe) SetBuffer ImageBuffer(img) LockBuffer ImageBuffer(img) z = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, (4278190080+(65536*r)+(256*g)+b) Next Next UnlockBuffer ImageBuffer(img) SetBuffer BackBuffer() Wobei vgf das filehandle ist in dem die Daten stehen und tsize die Größe in Byte. |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
Black |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Erm, wenn Blitzbasic einen halbwegs guten Compiler hat, dann sollte zwischen 256*256*256*255 und dem vorberechneten Wert kein Unterschied sein, will normalerweise der Compiler konstante Operationen in Compile-Time ausführt. | ||
![]() |
MercedBetreff: Das schnellste Bild gepixelt mit RLE |
![]() Antworten mit Zitat ![]() |
---|---|---|
So, nun wirds komplizierter ![]() Code: [AUSKLAPPEN] mem = CreateBank(tsize) hasread = ReadBytes(mem,vgf,0,tsize) If hasread <> tsize Then Return 0 img = CreateImage(tbreite, thohe) SetBuffer ImageBuffer(img) LockBuffer ImageBuffer(img) z = 0 ; ++++++++++++++++++++++++++++++++++++ uncompressed 24-bit image If t$ = "I24" For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, (4278190080+(65536*r)+(256*g)+b) Next Next EndIf ; ------------------------------------ uncompressed 24-bit image ; ++++++++++++++++++++++++++++++++++++ RLE compressed 24 bit image If t$ = "I3R" counted = 0 tocount = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 If counted = tocount ; Next RLE block tocount = PeekByte(mem, z) z = z + 1 compressed = False If tocount > 127 compressed = True tocount = tocount - 128 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 EndIf ; tcount > 127 tocount = tocount + 1 counted = 0 EndIf ; counted = tocount If Not compressed g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 EndIf WritePixelFast x, y, (4278190080+(65536*r)+(256*g)+b) counted = counted + 1 Next Next EndIf ; ------------------------------------ RLE compressed 24 bit image UnlockBuffer ImageBuffer(img) SetBuffer BackBuffer() t$ ist schlicht der interne Name des Subformats. Das Ergebnis der Einbindung von RLE war wie erwartet. Das hier so oft verwendete Bild von 512x512 ist ein Sternenhintergrund, dementsprechend gut klappt das mit RLE. Wie das RLE-Subformat aufgebaut ist sollte beim Lesen des RLE-Codes klar werden (das Komprimieren ist schwerer als das Anzeigen...) Vorteile: Die Größe der Bibliothek (die neben diesem Sternenbild bisher nur ein paar winzige Bilder beinhaltet die zusammen 7,6 KB ausmachen) ist von 775 auf 86 KB geschrumpft. Die Zeit zum Aufbau des Bildes auf erwähntem 400er Sellery ist von durchschnittlich 1563ms auf 1409ms gesunken (also 1/6 Sekunde gespart!) und noch besser: Die Ladezeit (um den Datenblock in den Speicher zu bringen ist von zuvor durchschnittlich 668ms auf 92ms gesunken. Zusammen gibt das eine Zeitersparnis von über 700ms. Dazu kommen noch etwa 100ms durch den Bufferwechsel, den Rallimen empfohlen hat und ein paar andere kleine Tweaks. Gesamtersparnis seit Öffnung des Threads: ca 850ms für den Aufbau des Bildes ![]() Danke an alle die was dazu beigetragen haben! Noch jemand eine Idee wie noch mehr rauszuholen ist? ![]() @Black Da hast Du sicherlich recht. Hast Du es mal ausgemessen? |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
soli |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habs jetzt nicht komplett durchgelesen.
Nur das hier 4278190080+(65536*r)+(256*g)+b) ist doch eine ständig wiederkehrende Berechung, oder habe ich mich verguckt? Warum berechnest du das nicht einmal vor Beginn der Schleife und schreibst das Ergebnis in ein Array? Pseudo: Dim gwert(255) Dim rwert(255) For laufvari=0 to 255 gwert(laufvari) = 256*laufvari rwert(laufvari) = 65536*laufvari next |
||
solitaire |
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm. Ja, ist eine gute Idee, soli.
Hab es mal getestet kam aber auf Werte jenseits der 2000 ms. Da schien es langsamer zu sein, doch dann hab ich die alten nochmal getestet und da waren es plötzlich über 3000 *bg* Muss den Rechner mal neu starten, aber das dauert bei der Schleuder immer so lange. Wenn ich einen realistischen Vergleich hab sag ich nochmal Bescheid. Danke für den Tipp ![]() Gruß Merced |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
![]() |
soli |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es kann halt niemand anders testen,
wenn er nicht deine spezielle Datei hat. ![]() Aber es muss schneller sein. Es stehen 512 Berechnungen gegen -zig Tausende. |
||
solitaire |
![]() |
Merced |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also nach einem kompletten Neustart des Rechners und allen Hintergrund-Programmen ausgeschaltet bekomme ich folgende Messwerte (jeweils 3 Testläufe) für den Aufbau des Bildes im Speicher:
Ohne Vorberechnung: 1383ms, 1360ms, 1336ms MIT Vorberechnung: 1339ms, 1347ms, 1340ms Zweimal schneller, einmal langsamer. Wobei man natürlich berücksichtigen muss dass es dabei eine erhebliche Messungenauigkeit gibt. Es scheint schneller zu sein, aber der Vorteil ist verschwindend gering, sofern er nicht durch Messungenauigkeit zustande kommt. Wie sich das erklärt? Keine Ahnung. Vielleicht ist Blitz schlau genug zu merken wenn oft dasselbe berechnet wird. Immerhin sind die meisten Pixel eher schwarz, da das Bild ein Sternenhintergund ist. Vielleicht ist der Unterschied zwischen Zugriff auf ein Array und erneute Berechnung auch wirklich nur so marginal. Wie auch immer, hier der neue Code: Code: [AUSKLAPPEN] ; ------ PreCalcs Dim precalcr(255) Dim precalcg(255) For z = 0 To 255 precalcr(z) = 4278190080+(65536*z) precalcg(z) = 256*z Next ... mem = CreateBank(tsize) hasread = ReadBytes(mem,vgf,0,tsize) If hasread <> tsize Then Return 0 img = CreateImage(tbreite, thohe) SetBuffer ImageBuffer(img) LockBuffer ImageBuffer(img) z = 0 ; ++++++++++++++++++++++++++++++++++++ uncompressed 24-bit image If t$ = "I24" For y = 0 To thohe-1 For x = 0 To tbreite-1 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 WritePixelFast x, y, (precalcr(r)+precalcg(g)+b) Next Next EndIf ; I24 ; ------------------------------------ uncompressed 24-bit image ; ++++++++++++++++++++++++++++++++++++ RLE compressed 24-bit image If t$ = "I3R" counted = 0 tocount = 0 For y = 0 To thohe-1 For x = 0 To tbreite-1 If counted = tocount ; Next RLE block tocount = PeekByte(mem, z) z = z + 1 compressed = False If tocount > 127 compressed = True tocount = tocount - 128 g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 EndIf ; tcount > 127 tocount = tocount + 1 counted = 0 EndIf ; counted = tocount If Not compressed g = PeekByte(mem, z) z = z + 1 b = PeekByte(mem, z) z = z + 1 r = PeekByte(mem, z) z = z + 1 EndIf ; not compressed WritePixelFast x, y, (precalcr(r)+precalcg(g)+b) counted = counted + 1 Next Next EndIf ; I3R ; ------------------------------------ RLE compressed 24-bit image UnlockBuffer ImageBuffer(img) SetBuffer BackBuffer() Noch jemand Ideen? ![]() |
||
http://www.starship-battles.de.vu
http://www.venture-interactive.de.vu |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja, diese kleinen Berechnungen zerren nicht soviel Speed und ein Lookup in einem Array kostet halt auch seine Zeit. | ||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group