AW: Geht das noch schneller? - Bitmap-Verrechnung
MulDiv basiert auf In64 und ist damit überlauf-sicher, was bei A*B div C imho nicht der Fall ist. Dafür ist es langsamer als der das einfache A*B DIV C.
Bezüglich des Performancevergleiches zielte ich eher auf 'MulDiv' vs. 'Round(A*B/C)' ab, also Floating Point Arithmetik. |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
|
AW: Geht das noch schneller? - Bitmap-Verrechnung
Um die bisherigen Ergebnisse zusammenzufassen:
* Zugriff auf ein Lookup-Array dauert länger, als die Berechnung. * MulDiv bringt eindeutig keine Beschleunigung * Im vorliegenden Fall bringt auch eine Parallelisierung nichts, da der Verwaltungsaufwand größer ist, als der Gewinn durch mehrere Prozessorkerne Das bislang schnellste Ergebnis liefert der untenstehende Code, egal, ob per Pointer-Addition oder Array-Zugriff:
Delphi-Quellcode:
procedure Draw32BitToBitmapxxx(const BitOben: TBitmap; BitUnten: TBitmap); // Array-Zugriff
var h,w,i, r, g, b: 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 RGBA_Unten^[w].rgbred := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbred - RGBA_Unten^[w].rgbred) shr 8 + RGBA_Unten^[w].rgbred); RGBA_Unten^[w].rgbGreen := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbgreen - RGBA_Unten^[w].rgbGreen) shr 8 + RGBA_Unten^[w].rgbGreen); RGBA_Unten^[w].rgbBlue := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbBlue - RGBA_Unten^[w].rgbBlue) shr 8 + RGBA_Unten^[w].rgbBlue); RGBA_Unten^[w].rgbReserved := 255; end; end; end; end; procedure Draw32BitToBitmapnew(const BitOben: TBitmap; BitUnten: TBitmap); // Pointer-Addition var h,w: Integer; RGBA_Unten, RGBA_Oben: ^TRGBQuad; // 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^.rgbReserved = 0 then begin // unten bleibt end else begin RGBA_Unten^.rgbBlue := ((RGBA_Oben^.rgbReserved * (RGBA_Oben^.rgbBlue - RGBA_Unten^.rgbBlue)) shr 8 + RGBA_Unten^.rgbBlue); RGBA_Unten^.rgbGreen := ((RGBA_Oben^.rgbReserved * (RGBA_Oben^.rgbgreen - RGBA_Unten^.rgbGreen)) shr 8 + RGBA_Unten^.rgbGreen); RGBA_Unten^.rgbred := ((RGBA_Oben^.rgbReserved * (RGBA_Oben^.rgbred - RGBA_Unten^.rgbred)) shr 8 + RGBA_Unten^.rgbred); RGBA_Unten^.rgbReserved := 255; end; inc (RGBA_Unten); inc (RGBA_oben); end; end; end; |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
Vielleicht über die Parallel FOR ok, kann ich nicht nachvollziehen. Aber einen optimierten thread mit entsprechendem vorbereiteten Prozessen müsste schneller sein. Können wir am Sa. ja mit unserem Thread König, emm Kaiser, ich meine Kaisler diskutieren. :stupid: Mavarik |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Hallo, ich bin hier neu hinzugestoßen und versuche mich am Beschleunigen.
Zuförderst ein paar Fragen zu den Details: ● Ist der Nenner in der Formel 255 oder 256? Bei 255 sind einige Klimmzüge nötig ● Ist Round vonnöten, oder dient es nur zur Float-Integer-Konvertierung? ● Von welcher WEB-Site kann ich 2 repräsentative 32-bittige Bitmaps absaugen? Da ich schon einmal mit MMX-Befehlen Antialiasing veranstaltet habe, würde ich mich gern an der Bitmap-Verrechnung versuchen. MfG Manfred(19)42 |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
Muss man quasi im Einzelfall testen, wo was schneller ist. |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
Round wäre gut, zur Not aber auch ohne. Erstelle Dir doch einfach selber 2 passende Bitmaps, hier die Größe und Bedingungen, mit denen ich hier teste: - 3548x2558 Pixel, 32 Bit-Format. - Das untere Bitmap hat einen Verlaufsuntergrund, das obere Bitmap hat zwei rechteckige Bereiche (jeweils 340 x 2300), die zu 100% transparent sind. |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Danke für den Ratschlag (um diese Uhrzeit)!
Ich hatte mit 2 kleineren Bitmaps experimentiert und werde dem Ratschlag folgen. Jetzt habe die letzte (Pointer)-Version der Prozedur probiert. Sie läuft sehr flott und schreit förmlich nach dem Einsatz von MMX-Code. An einer Thread-Version will ich mich später versuchen. Ich habe da schon eine Idee. Bei Threads bin ich aber nicht sehr sattelfest. Auf meinem DualCore-Notebook für Rentner wird es nicht viel bringen Wenn ich mit den technischen Rahmenbedingungen der DP mehr vertraut bin, werde ich auch Codepassagen präsentieren. Gute Nacht! |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Delphi-Quellcode:
PROCEDURE Blend32(Source,Dest:pRGBQuad; Width,Height,OOffset,UOffset:Integer);
const RegSize=4; WOffs=6*RegSize; HOffs=12*RegSize; OOffs=11*RegSize; UOffs=10*RegSize; asm pushad mov ebp,ecx // Width lea esi,[eax+ebp*4] // Source lea edi,[edx+ebp*4] // Dest neg ebp mov [esp+WOffs],ebp @Loop: mov bl,[esi+ebp*4].TRgbQuad.rgbReserved // S.Reserved test bl,bl jz @Next // Red mov al,[esi+ebp*4].TRgbQuad.rgbRed // S.Red mov cl,[edi+ebp*4].TRgbQuad.rgbRed // D.Red sub al,cl // S.Red-D.Red imul bl // (S.Red-D.Red)*S.Reserved add ah,cl // ((S.Red-D.Red)*S.Reserved) shr 8 + D.Red mov dx,ax // Green mov al,[esi+ebp*4].TRgbQuad.rgbGreen // S.Green mov cl,[edi+ebp*4].TRgbQuad.rgbGreen // D.Green sub al,cl // S.Green-D.Green imul bl // (S.Green-D.Green)*S.Reserved mov dl,ah // ((S.Green-D.Green)*S.Reserved) shr 8 add dl,cl // ((S.Green-D.Green)*S.Reserved) shr 8 + D.Green shl edx,8 // Blue mov al,[esi+ebp*4].TRgbQuad.rgbBlue // S.Blue mov cl,[edi+ebp*4].TRgbQuad.rgbBlue // D.Blue sub al,cl // S.Blue-D.Blue imul bl // (S.Blue-D.Blue)*S.Reserved mov dl,ah // ((S.Blue-D.Blue)*S.Reserved) shr 8 add dl,cl // ((S.Blue-D.Blue)*S.Reserved) shr 8 + D.Blue // Reserved or edx,$FF000000 mov [edi+ebp*4],edx add ebp,1 jl @Loop // Nächste Zeile @Next: add esi,[esp+OOffs] add edi,[esp+UOffs] mov ebp,[esp+WOffs] sub [esp+HOffs],1 jnz @Loop @End: popad end;
Delphi-Quellcode:
PROCEDURE AsmDraw32BitToBitmap(Source,Dest:TBitmap);
resourcestring sWidthDifferent='Bitmaps haben unterschiedliche Breiten'; sHeightDifferent='Bitmaps haben unterschiedliche Höhen'; sZeroWidth='Breite der Bitmaps ist 0'; sLessTwoLines='Höhe der Bitmaps ist < 2'; sSourceNone32Bit='Source ist keine 32 Bit Bitmap'; sDestNone32Bit='Dest ist keine 32 Bit Bitmap'; var PSource,PDest:pRGBQuad; W,H,SOffset,DOffset:Integer; begin W:=Source.Width; H:=Source.Height; if Dest.Width<>W then raise Exception.Create(sWidthDifferent); if Dest.Height<>H then raise Exception.Create(sHeightDifferent); if W<1 then raise Exception.Create(sZeroWidth); if H<2 then raise Exception.Create(sLessTwoLines); if Source.PixelFormat<>pf32bit then raise Exception.Create(sSourceNone32Bit); if Dest.PixelFormat<>pf32bit then raise Exception.Create(sDestNone32Bit); PSource:=Source.ScanLine[0]; SOffset:=NativeInt(Source.ScanLine[1])-NativeInt(PSource); PDest:=Dest.ScanLine[0]; DOffset:=NativeInt(Dest.ScanLine[1])-NativeInt(PDest); Blend32(PSource,PDest,W,H,SOffset,DOffset); end; |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
Wie an anderer Stelle schon dargestellt sollte die Implementierung mit Hilfe von SIMD Befehlen mehr bringen. Wenn Du dabei lieber mit Pascal als mit Assembler arbeitest, dann schau Dir doch mal Vector-Pascal : http://sourceforge.net/projects/vectorpascalcom/ http://www.dcs.gla.ac.uk/~wpc/report...index/x25.html an. Ist zwar schon einige Zeit her das ich damit gespielt habe, aber damals konnte ich damit eine DLL erstellen und die Funktionen in Delphi einbinden und für solche Probleme wie Deines war das Teil ideal. hth HaJoe |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:21 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