AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Geht das noch schneller? - Bitmap-Verrechnung

Ein Thema von Harry Stahl · begonnen am 22. Nov 2014 · letzter Beitrag vom 5. Jan 2015
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:34
Selbst dieser Versuch, einen lokalen TRGBQuad zu verwenden (cu- und co-Variablen), führt bei 5 Durchläufen, bei einem Bitmap von ca. 3500x2500 Pixel zu 300 MS mehr Zeit:

Delphi-Quellcode:
procedure Draw32BitToBitmapNew(const BitOben: TBitmap; BitUnten: TBitmap);
var
   h,w,i: Integer;
   RGBA_Unten, RGBA_Oben: pRGBALine;
   cu, co : TRGBQuad;
begin
   For h := 0 to BitUnten.Height-1 do begin
     RGBA_Unten := BitUnten.ScanLine[h];
     RGBA_Oben := BitOben.ScanLine[h];

     For w:= 0 to BitUnten.Width-1 do begin
       if RGBA_Oben^[w].rgbReserved = 0 then begin
         // unten bleibt
       end else begin
         cu := RGBA_Unten^[w];
         co := RGBA_Oben^[w];

         i := Round (cu.rgbBlue - ((cu.rgbBlue - co.rgbBlue) / 255 * co.rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbBlue := 0 else if i > 255 then RGBA_Unten^[w].rgbBlue := 255 else RGBA_Unten^[w].rgbBlue := i;

         i := Round (cu.rgbGreen - ((cu.rgbGreen - RGBA_Oben^[w].rgbGreen) / 255 * co.rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbGreen := 0 else if i > 255 then RGBA_Unten^[w].rgbGreen := 255 else RGBA_Unten^[w].rgbGreen := i;

         i := Round (cu.rgbRed - ((cu.rgbRed - co.rgbRed) / 255 * co.rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbRed := 0 else if i > 255 then RGBA_Unten^[w].rgbRed := 255 else RGBA_Unten^[w].rgbRed := i;

         RGBA_Unten^[w].rgbReserved := 255;
       end;
    end;
   end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#12

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:48
Die hier oft verwendete "255" finde ich nicht ganz so dolle, denn 0..255 sind 256 Werte, also setze man doch lieber alle "0..255" Werte mit 256 ins Verhältnis, dann gibt es auch keine Resultate > 255...
Was meinst Du hiermit genau?

Ich vermute mal, eine x in 0..255 Prüfung braucht mehr Zeit und ich weiß dann immer noch nicht, ob x evtl. kleiner als 0 (dann schwarz) oder größer 255 ist (dann weiß).
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
670 Beiträge
 
#13

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:50
Schon mal bei/mit Graphics32 versucht?!
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.178 Beiträge
 
Delphi 12 Athens
 
#14

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 12:00
länger:

Ist ein bissl erschreckend, aber liegt auch an deiner Speicherverwaltung. (zuviele ungünstig liegende Variablen)
Integer-Operationen werden in den CPU-Registern (EAX usw.) durchgeführt.
Die Fließkommaoperationen in den FPU-Registern, wobei EAX und Co. frei bleibt.

Das Selbe würde dann auch bei den Streaming-Registern auftreten.

Und warum eigentlich ständig RGBA_Unten^[w] und nicht Anfangs mal in eine Variable?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#15

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 12:21
Ich verwende "/256" statt "/255".

MulDiv ist live wegen der internen multiplen 32Bit über Int64 Logik Langsamer als aktuelle FPU Nutzung, aber mit ging es ums erkennen des Prinzips!

wenn aus "Round (RGBA_Unten^[w].rgbBlue - ((RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) / 255 * RGBA_Oben^[w].rgbReserved));"
besser "RGBA_Unten^[w].rgbBlue - ((RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) * RGBA_Oben^[w].rgbReserved) div 255; //<div 256> oder besser <shr 8>;" wird...
also geht das auch in 32Bit(Integer) ohne Muldiv völlig ohne Genauigkeitsverlust, weil eben ohne Informationsverlust erst multipliziert und dann dividiert wird.

Nochmal im Detail:
- du hast zwei 8Bit (Farb)Werte, die können multipliziert max. einen 16Bit Wert ergeben(0.65535), welcher Locker in eine 32 Bit passt
- ein "SHR 8" ist minimal schneller wie ein "DIV 256"
- mit glatten 2er Potenzen zu rechnen schadet nie

Also:
Du hast 2 Farbwerte welche du multiplizierst und fix wieder durch 255teislt(oder 256 bzw. um 8 rechts schiebst)... das geht, ist aber per möglicher Tabelle 1 aus 65536(2^16) im Indexbereich von 0.65535 mit vor berechneten Einträgen am schnellsten:

RelColResult:=RelColTable[(ColValueA shl 8)+ColValueB];
("RelColTable" sein ein Array 0..65535 of BYTE)



(Ich rechne das irgendwie anders, deshalb erschließt sich mir der Sinn deine nachfolgenden Abfrage aus ">255" nicht, denn mir fällt kein Wertepaar der 2 Ausgangsfarben ein, wo das Ergebnis >255 sein kann... Nur weil Round auch "aufrundet" passiert dir das eventuell... Ich denke wenn du Round durch Floor ersetzt kannst du dir das "if" sparen und Kommafarbwerte gibt es bei 8Bit 0.255 eh nicht )
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 12:42
wenn ich Round durch Floor ersetze, dauert es 3 mal so lang...
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#17

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 13:08
Ich glaube, Du könntest Recht haben, mit der Vermutung, dass es eigentlich nie größer als 255 werden kann, da ja von einem Ausgangswert, der nie größer als 255 sein kann, immer etwas abgezogen wird. Also muss man in der Tat nur den <0 Fall berücksichtigen.

Auch /256 statt /255 müsste richtig sein, da es ja um die Anzahl der möglichen Farbabstufungen geht.

Super!!

Das umgesetzt werden laut AQTime pro Aufruf der Funktion ca. 20 MS gespart

Das Ding sieht jetzt also so aus:

Delphi-Quellcode:
procedure Draw32BitToBitmapNew(const BitOben: TBitmap; BitUnten: TBitmap);
var
   h,w,i: Integer;
   RGBA_Unten, RGBA_Oben: pRGBALine;
begin
    for h := 0 to BitUnten.Height-1 do begin
     RGBA_Unten := BitUnten.ScanLine[h];
     RGBA_Oben := BitOben.ScanLine[h];

     For w:= 0 to BitUnten.Width-1 do begin
       if RGBA_Oben^[w].rgbReserved = 0 then begin
         // unten bleibt
       end else begin
         i := Round (RGBA_Unten^[w].rgbBlue - ((RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) / 256 * RGBA_Oben^[w].rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbBlue := 0 else RGBA_Unten^[w].rgbBlue := i;

         i := Round (RGBA_Unten^[w].rgbGreen - ((RGBA_Unten^[w].rgbGreen - RGBA_Oben^[w].rgbGreen) / 256 * RGBA_Oben^[w].rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbGreen := 0 else RGBA_Unten^[w].rgbGreen := i;

         i := Round (RGBA_Unten^[w].rgbRed - ((RGBA_Unten^[w].rgbRed - RGBA_Oben^[w].rgbRed) / 256 * RGBA_Oben^[w].rgbReserved));
         if i < 0 then RGBA_Unten^[w].rgbRed := 0 else RGBA_Unten^[w].rgbRed := i;

         RGBA_Unten^[w].rgbReserved := 255;
       end;
    end;
   end;
end;

Geändert von Harry Stahl (22. Nov 2014 um 13:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#18

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 14:03
Jetzt noch mal Ergebnisse bei Parallelisierung des ganzen mit TParallel:

Auf 2-Kern-Rechner von ca. 300 MS auf 150
Auf 4-Kern-Rechner von ca. 300 MS auf 100
Auf 6-Kern-Rechner von ca. 300 MS auf 56

Also fast 6 mal so schnell!!

Jetzt lohnt sich das mit den Kernen so richtig, insbesondere bei den rechenintensiven Grafikbearbeitungsaufgaben eine echt hilfreiche Sache.

Also was das angeht, bringt XE7 voll den Turbo!!

Mein nächster Entwicklungsrechner wird also mit mindestens 6 Kernen kommen...
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#19

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 16:23
Eine Bitte:
mach dir mal für mich die Mühe und "messe" die Zeiten noch für diese 2 Varianten:

i := RGBA_Unten^[w].rgbBlue - (((Int(RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) * Int(RGBA_Oben^[w].rgbReserved)) div 256);
und
i := RGBA_Unten^[w].rgbBlue - (((Int(RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) * Int(RGBA_Oben^[w].rgbReserved)) shr 8);

(für je alle 3 Farben halt)

Das wird genauso exakt und "müsste" schneller sein... Das "div 256" und "shr 8" könnte sogar der Compiler optimieren, wenn es keinen Unterschied machen sollte.

Bin gespannt auf deine Ergebnisse
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 16:32
Mache ich doch gerne. Rückmeldung zu Variante 1+2:

E2015: Operator ist auf diesen Operandentyp nicht anwendbar.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz