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 6. Jan 2015
Antwort Antwort
Seite 1 von 8  1 23     Letzte »    
Benutzerbild von Harry Stahl
Harry Stahl

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

Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 03:00
Mit dieser Funktion wird eine 32-Bitmap - unter Berücksichtigung der Transparenz auf einen Konstanten Untergrund (die Hintergrund-Bitmap) gemalt.

Mal abgesehen von Parallel-Berechnung mit TParallel (was ich schon erledigt habe, hier die einfache Version, um die Funktion leichter nachvollziehen zu können), kann man das noch irgendwie schneller berechnen?

Delphi-Quellcode:
// Setz vorraus, dass die Bitmaps die gleiche Größe haben!!!
procedure Draw32BitToBitmapold(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) / 255 * RGBA_Oben^[w].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 (RGBA_Unten^[w].rgbGreen - ((RGBA_Unten^[w].rgbGreen - RGBA_Oben^[w].rgbGreen) / 255 * RGBA_Oben^[w].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 (RGBA_Unten^[w].rgbRed - ((RGBA_Unten^[w].rgbRed - RGBA_Oben^[w].rgbRed) / 255 * RGBA_Oben^[w].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
hstreicher

Registriert seit: 21. Nov 2009
220 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 09:21
schneller wird es wenn man die Formeln umbau so dass mit Integer anstatt Floats gerechnet wird,

und die geschachtelten Abfragen so umstellen dass das wahrscheinlich häuftigste Ergebnis zuerst abgeprüft wird
um den 2. Vergleich zu vermeiden
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 09:52
Mhh, wenn ich integer verwende, wird es ungenau. Aber wäre vielleicht akeptabel, wenn es nur um Anzeige eines Ergebnisses geht ( im Unterschied zu einem konkret weiterverwendbaren Ergebnis).

Das wahrscheinlichste Ergebis ist, dass der Wert zwischen 0 und 255 liegt, aber das muss ich zuvor durch Überprüfung sicherstellen, komme da also nicht dran vorbei...
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.197 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 10:10
Hast du eigentlich schon mal mit AQTime geprüft?

Ich vermute wenn du für RGBA_Unten^[w] und Co. Lokale Variablen verwendest wird es auch schneller
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 10:38
Parallele Berechnung mehrerer Bytes = Streaming-Funktionen ala 3DNow!, MMX, SSE, AVX, FMA

Da kann man "gleichzeitig", in einem Thread, mit 128 Bit (z.B. 8 Byte) oder gar 256 Bit rechnen, also mit mindestens 2 Color-Dingern (a 4 Bytes) in einem Rutsch.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

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

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:37
@ Berhard: Klar, AQTime (Prof) ist mein ständiger Begleiter.

Lokale Variablen zu verwenden, bringt im vorliegenden Fall leider nichts, weil die Zuweisung an die lokalen Variablen in der Summe länger braucht (ca. 30%), als der Zugriff auf den Speicher:

Delphi-Quellcode:
procedure Draw32BitToBitmapNew(const BitOben: TBitmap; BitUnten: TBitmap);
var
   h,w,i: Integer;
   rublue, rugreen, rured, rureserved,
   roblue, rogreen, rored, roreserved: Byte;
   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
         rublue := RGBA_Unten^[w].rgbBlue;
         rugreen := RGBA_Unten^[w].rgbGreen;
         rured := RGBA_Unten^[w].rgbred;
         rureserved := RGBA_Unten^[w].rgbreserved;

         roblue := RGBA_Oben^[w].rgbBlue;
         rogreen := RGBA_Oben^[w].rgbGreen;
         rored := RGBA_Oben^[w].rgbred;
         roreserved := RGBA_Oben^[w].rgbreserved;

         i := Round (ruBlue - ((ruBlue - roBlue) / 255 * roReserved));
         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 (ruGreen - ((ruGreen - roGreen) / 255 * roReserved));
         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 (ruRed - ((ruRed - roRed) / 255 * roReserved));
         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.537 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:38
@himitsu:

MMX,SSE Streaming-Funktionen: Noch nie verwendet. Wie nutzt man das?
Muss ich Assembler verwenden? Gibt es Beispiele für Bitmap-Verwendung?
  Mit Zitat antworten Zitat
mensch72

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 11:51
man nehme einfach "MULDIV" für solche Berechnungen in Integer ohne Genauigkeitsverlust.

aus: i := Round (RGBA_Unten^[w].rgbBlue - ((RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) / 255 * RGBA_Oben^[w].rgbReserved));
wird dann: i := RGBA_Unten^[w].rgbBlue - MulDiv(RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue, RGBA_Oben^[w].rgbReserved, 255);

Mit Zusatzvariable und nur einer Dereferenzierung am Schleifenanfang, also "col:=RGBA_Unten^[w]" und dann nur mit "col.rgbXXX" rechnen wird es nochmal schneller.
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...

Ansonsten rechne ich das lieber komplett auf Speicherarrays und verwende simple Indexzugriffe auf vor berechnete Wertetabellen(statt ständiges "MulDiv" von zwei "8Bit" Werten) sowie das Ganze möglichst als vorzeichenlose Ganzzahlarithmetik, das ist noch schneller und damit sind dann auch so Sachen wie SSEx für weiter Filteroperationen und andere Spielereien möglich. Das führt aber hier zuweit. Einen Blick in die SourceCodes von optimierten Grafiklibs würde ich da empfehlen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 12:19
Ob es dafür bereits fertige Bibliotheken gibt, weiß ich nicht, aber am Ende kommt es auf Assembler hinaus, da Pascal das natürlich nicht direkt unterstützt (ob du das nunb schreibst, oder jemand anderes)

Ich war mal vor Jahren auf die Idee gekommen, die Operationen in einem Record zu kapseln (Record Operatoren und Methoden), aber da ich selber keinen Anwendungsfall und nicht wirklich Zeit hatte .......

Bezüglich des MulDiv:
Jupp, solange du bei Integer-Operationen bleibst, sollte es etwas schneller gehen.
Bezüglich dem (Auf)Runden kann man einfach bissl was Aufaddieren, vor dem Dividieren.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (22. Nov 2014 um 12:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

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

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 22. Nov 2014, 12:24
Also, nur statt "/" ein div zu nehmen und das round wegzulassen (also nur mit Integer zu rechnen), benötigt ca. 30% mehr Zeit.

Mit MultiDiv zu arbeiten, dauert gar direkt 100% länger.

Aber die anderen beschriebenen Ansätze werde ich auch mal versuchen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 8  1 23     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 11:48 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