AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?
Thema durchsuchen
Ansicht
Themen-Optionen

Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

Ein Thema von Harry Stahl · begonnen am 21. Feb 2016 · letzter Beitrag vom 28. Feb 2016
Antwort Antwort
Seite 1 von 2  1 2      
Rollo62

Registriert seit: 15. Mär 2007
4.174 Beiträge
 
Delphi 12 Athens
 
#1

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 10:36
Mich würde generell interessieren ob man solche Abläufe nicht auch in der GPU machen kann.

Ich denke das ist genau der Gund warum GPU-unterstützte Software soviel schneller ist.
Habe aber 0-Erfahrung damit.

Als Vorraussetzung wäre dann vielleicht das die GPU direkt im Haupsspeicher (shared) arbeiten kann, weil sonst wieder kopiert werden müssten.

Kennt sich da jemand aus ?

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 12:52
So ich habe mich mal an SSE versucht.
Es scheint zu funktionieren (hab jetzt keine Bilder wo ichs richtig testen könnte), aber wie schnell/langsam das ist und ob der
Code wirklich fehlerfrei ist kann ich nicht sagen. Habe bisher noch nie was mit SSE gemacht.

Und das Bitmap sollte ein Vielfaches von 4 Pixeln groß sein, sonst knallts wahrscheinlich bzw. man müsste das abfangen.

Delphi-Quellcode:
function IsPartlyTransparent(fromScanline: Pointer; toScanline: Pointer): Boolean;
const pattern: Array[0..3] of Cardinal = ($FF000000, $FF000000, $FF000000, $FF000000);
label schleife, transparent, ende;
var IsTransparent: Array[0..15] of Byte; // "GigaBool" (128 Bit)
asm
  movups xmm2, pattern
schleife:
  movups xmm1, [eax]
  ANDPS xmm1, xmm2
  CMPEQPS xmm1, xmm2
  movntps IsTransparent, xmm1
  cmp dword ptr IsTransparent, 0
  jz transparent
  add eax, $10
  cmp eax, edx
  jb schleife
  mov Result, false
  jmp ende
transparent:
  mov Result, true
ende:
end;
Aufruf:

IsPartlyTransparent(bmp.ScanLine[bmp.Height-1],bmp.ScanLine[0]) Du kannst ja einfach mal schauen was dabei rum kommt.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.560 Beiträge
 
Delphi 12 Athens
 
#3

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 18:17
Vielen Dank für die weiteren Bemühungen.

Deine vorletzte Variante ist nun ca. 1 MS schneller als meine.
Die letzte Variante stürzt immer ab.

Du kannst übrigens auch mit Delphi 2010 mein Demo, dass ich hier hochgeladen habe, verwenden, entfernst halt nur System.Threading und System.syncobjects und die Variante mit TParallel, dann hast Du eine 32-Bit-Bitmap und kannst diese per Schalter auch mit Transparenz versehen.
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.100 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 23:42
So ich habe mich mal an SSE versucht.
Es scheint zu funktionieren (hab jetzt keine Bilder wo ichs richtig testen könnte), aber wie schnell/langsam das ist und ob der
Code wirklich fehlerfrei ist kann ich nicht sagen. Habe bisher noch nie was mit SSE gemacht.

Und das Bitmap sollte ein Vielfaches von 4 Pixeln groß sein, sonst knallts wahrscheinlich bzw. man müsste das abfangen.

Delphi-Quellcode:
function IsPartlyTransparent(fromScanline: Pointer; toScanline: Pointer): Boolean;
const pattern: Array[0..3] of Cardinal = ($FF000000, $FF000000, $FF000000, $FF000000);
label schleife, transparent, ende;
var IsTransparent: Array[0..15] of Byte; // "GigaBool" (128 Bit)
asm
  movups xmm2, pattern
schleife:
  movups xmm1, [eax]
  ANDPS xmm1, xmm2
  CMPEQPS xmm1, xmm2
  movntps IsTransparent, xmm1
  cmp dword ptr IsTransparent, 0
  jz transparent
  add eax, $10
  cmp eax, edx
  jb schleife
  mov Result, false
  jmp ende
transparent:
  mov Result, true
ende:
end;
Aufruf:

IsPartlyTransparent(bmp.ScanLine[bmp.Height-1],bmp.ScanLine[0]) Du kannst ja einfach mal schauen was dabei rum kommt.
Hallo Neutral General,

m.E. kann die Funktion nur sehr eingeschränkt funktionieren.

1) Überprüfter Bereich der Bitmap:
Als Parameter werden der Funktion die Adressen des jeweils ersten Pixels der ersten und letzten Zeile übergeben.
Du prüfst die Pixel ab Anfang der "ersten" Zeile bis zum Anfang der "letzten" Zeile.
Wenn also ein transparentes Pixel irgendwo in der letzten Zeile ist, wird das nicht erkannt.

2) Prüfung von jeweils 4 Pixeln auf Transparenz:
Du liest 4 Pixel=16 Bytes in XMM1 machst ein AND mit dem Pattern und vergleichst das Ergebnis mittels CMPEQPS mit dem Pattern.
Bei diesem Vergleich werden alle Bits der Singles, bei denen der Vergleich True ergibt, = 1 gesetzt, andernfalls = 0.
Dann schreibst Du XMM1 in das 16 Byte Array "IsTransparent" und prüfst das erste DWord dieses Array auf 0.
Das heißt du prüfst immer nur das erste von jeweils 4 Pixeln auf Transparenz, die übrigen 3 von 4 Pixeln bleiben ungeprüft.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.100 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 23:45
Hallo Harry:
Ich hab mir mal die Mühe gemacht, mehrere ASM-Routinen zu schreiben, die alle recht flink arbeiten, und zusätzlich ein kleines Testprogramm.

Zu den Asm-Routinen:
1) IsPartlyTransparentAsm
Als 32 Bit und als 64 Bit Version vorhanden.
Die Routine prüft ganz simpel Pixel für Pixel

2) IsPartlyTransparentAsmQW
Nur als 64 Bit Version vorhanden.
Die Routine nutzt die 64 Bit Register und prüft jeweils 2 Pixel auf einmal.

3) IsPartlyTransparentAsmSSE
Als 32 Bit und als 64 Bit Version vorhanden.
Die Routine nutzt sie 128 Bit Register und prüft jeweils 4 Pixel auf einmal.

Bei einer Bitmap in der von dir vorgeschlagenen Größe von 4244 x 2819 werden folgende Zeiten genannt:

8 ms IsPartlyTransparentAsm 32 Bit
4 ms IsPartlyTransparentAsmSSE 32 Bit
8 ms IsPartlyTransparentAsm 64 Bit
5 ms IsPartlyTransparentAsmQW 64 Bit
4 ms IsPartlyTransparentAsmSSE 64 Bit

Vielleicht schaust Du dir das mal an.
Ich habe die Routinen mit verschiedenen Parametern getestet und keine Fehler bemerkt.
Angehängte Dateien
Dateityp: zip Transparent.zip (744,9 KB, 14x aufgerufen)
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.560 Beiträge
 
Delphi 12 Athens
 
#6

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 24. Feb 2016, 17:34
Hallo Harry:
Ich hab mir mal die Mühe gemacht, mehrere ASM-Routinen zu schreiben, die alle recht flink arbeiten, und zusätzlich ein kleines Testprogramm.
Wow, bin beeindruckt

In der Anlage ein Screenshot mit den Testergebnissen. Meine AMD-CPU ist halt doch ein Ticken langsamer.

Was mich aber wundert, sind die z.T. erheblichen Schwankungen beim gleichen Test (SSE: 13 / 25 MS).

32- oder 64-Bit macht keinen nennenswerten Unterschied.
Angehängte Grafiken
Dateityp: jpg Results.jpg (88,6 KB, 23x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Valle
Valle

Registriert seit: 26. Dez 2005
Ort: Karlsruhe
1.223 Beiträge
 
#7

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 24. Feb 2016, 18:00
Eine andere Möglichkeit wäre es, mehrere Threads zur Bearbeitung bereits vorher zu starten und erst bei Bedarf zu aktivieren.

Das sollte den Overhead reduzieren und die Ausführungsgeschwindigkeit durch Parallelisierung dennoch erhöhen. Es wäre nur ein Minimum an Synchronisation nötig. Soweit ich das sehe, würde es reichen das Bild in n halbwegs gleichgroße Abschnitte zu unterteilen und dann auf die n Threads loszulassen. Der Hauptthread könnte darauf warten, bis alle Threads fertig sind.

Vermutlich wäre das noch schneller als die Single-Core Lösungen. Allerdings auch etwas aufwendiger zu implementieren.
Valentin Voigt
BOFH excuse #423: „It's not RFC-822 compliant.“
Mein total langweiliger Blog
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.560 Beiträge
 
Delphi 12 Athens
 
#8

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 24. Feb 2016, 18:37
Also die Single-Core-Lösung die hier am schnellsten ist, ist die aus "IsPartlyTransparentASM" (unter AQTime wird die in Average-Time ca. 20 MS schneller angezeigt, als meine Standard-Variante. Im Einzeltest sind die aber fast gleichschnell. Keine Ahnung, warum hier so Unterschiede entstehen. Bei AQTime gab es allerdings ca. 26 Durchläufe).

Die Variante habe ich hier mal auf meine Aufrufkonvention umgestaltet, um nicht doppelte Funktionsaufrufe zu haben.

Frage an die ASM-Experten: Kann man das noch etwas schöner machen?
Delphi-Quellcode:
function HasTransparentRGBAValues (const bm:TBitmap): Boolean;
var
  W,H:NativeInt; P0,P1:Pointer;
begin
  P0 := bm.ScanLine[0]; p1 := bm.ScanLine[1];
  w := bm.Width; h:= bm.Height;

  asm
  // EAX=P0, Zeigt auf Zeile 0 der Bitmap
  // EDX=P1, Zeigt auf Zeile 1 der Bitmap
  // ECX=W, Breite der Bitmap
  // Stack=H, Höhe der Bitmap

                 mov EAX,P0 // von mir ergänzt
                 mov EDX,P1 //
                 mov ECX,w //

                 sub edx,eax // Offset von Zeile 1 zu Zeile 0
                 js @BottomUp
                 imul edx,H // Bytes/Zeile*Zeilen
                 add eax,edx // Auf unterste Zeile
  @BottomUp: lea eax,[eax+ecx*4+3] // Hinter letztes Pixel (auf A-Byte)
                 imul ecx,H // Anzahl Pixel
                 neg ecx
  @Loop: cmp byte[eax+ecx*4],$FF
                 jne @True
                 add ecx,1
                 jl @Loop
                 xor al,al
                 jmp @End
  @True: mov al,True
  @End:
  end;
end;
Edit: Hmmmh... irgendwas scheint an der procedure aber noch nicht zu stimmen, denn an einer Stelle des Programmablaufs stimmt plötzlich etwas nicht mehr (beim ersten Ausblenden der Hintergrundebene wird das Schachmuster plötzlich nicht mehr angezeigt, sondern eine weiße Arbeitsfläche, also irgendwo liefert die Funktion anscheinend einmal ein falsches Ergebnis zurück)

Geändert von Harry Stahl (24. Feb 2016 um 18:52 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.100 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 25. Feb 2016, 02:55
Hallo Harry:
Ich hab mir mal die Mühe gemacht, mehrere ASM-Routinen zu schreiben, die alle recht flink arbeiten, und zusätzlich ein kleines Testprogramm.
Wow, bin beeindruckt

In der Anlage ein Screenshot mit den Testergebnissen. Meine AMD-CPU ist halt doch ein Ticken langsamer.

Was mich aber wundert, sind die z.T. erheblichen Schwankungen beim gleichen Test (SSE: 13 / 25 MS).

32- oder 64-Bit macht keinen nennenswerten Unterschied.
Hallo Harry,
zu "Was mich aber wundert, sind die z.T. erheblichen Schwankungen beim gleichen Test (SSE: 13 / 25 MS)."

Ich habe (bei allen Funktionen) ähnliche Schwankungen gesehen, allerdings nur, wenn ich das als "Release" compiliert hatte.
Bei "Debug" waren die Schwankungen eher im Normalbereich.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 24. Feb 2016, 08:40
m.E. kann die Funktion nur sehr eingeschränkt funktionieren.

1) Überprüfter Bereich der Bitmap:
Das ist mir im Nachhinein auch noch aufgefallen, stimmt.

2) Prüfung von jeweils 4 Pixeln auf Transparenz:
Nachdem ich gerade CMPEQPS nochmal nachgeschlagen habe, muss ich sagen: Auch da hast du Recht.
Ich hatte es so gelesen, dass es entweder nur ein true für "alles ist gleich" oder ein false "irgendwas ist anders" gibt.

Okay dann ist meine SSE-Variante wohl Schrott
Ein Versuch wars Wert
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 01:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz