Einzelnen Beitrag anzeigen

Amateurprofi

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

AW: Floyd-Steinberg Dithering

  Alt 30. Nov 2023, 21:11
Ich bin mir nicht sicher, ob du meine Ausführung mit der Sprungvorhersage verstanden hast, wenn du eine aufsteigende Sequenz zwischen x und y testest, ist das witzlos, denn die Daten bei einer reellen Berechnung liegen nicht in dieser Form vor. In den Daten im Test, wo du von -111 bis 366 gehst hast du nun 112 mal jle jump taken, 366 mal non taken, und dann 255 mal jbe jump taken, 111 mal non taken, immer hintereinander, da ist die Sprungvorhersage immernoch fast immer richtig.
Realistische Werte erhälst du nur, wenn du die Werte nicht in auf- oder absteigender Reihenfolge an die Funktion fütterst sondern in einer realistischen Verteilung durchgemischt.
Danke Stevie,
tschuldi, dass ich so spät antworte. Ich hatte diesen Text schon vor 2 Wochen geschrieben, mich dann aber um andere Themen gekümmert.

Ich bin mir sicher, dass ich Deine Ausführungen verstanden hatte und ich bin mir auch sicher, dass ich das auch schon vorher wusste.
Ich habe die CMOV-Instruktion immer gemieden, weil sie nicht von allen Prozessoren unterstützt wird, was allerdings eine recht alte Information ist.
Ich habe die Testprozeduren noch einmal überarbeitet.
Die zu vergleichenden Werte kommen jetzt aus einem Daten-Array, das mit Zufallswerten, und bei einem zweiten Testlauf mit aufsteigenden Werten gefüllt ist.
Die Laufzeiten sind immer recht unterschiedlich, typische Werte waren:
Code:
Zufallswerte
1,360  2,184  3,926  CPU-Ticks TestCMovShort
2,602  4,243  20,340  CPU-Ticks TestMov
1,242  2,059  16,414  CPU-Ticks Differenz
Aufsteigende Werte
1,360  1,501  27,828  CPU-Ticks TestCMovShort
1,614  1,755  27,457  CPU-Ticks TestMov
254  254  -371  CPU-Ticks Differenz
Der fragliche Code wird für jedes Pixel der Bitmap 4 Mal ausgeführt.
Ausgehend von dem Gewinn von 1242 CPU-Ticks für 478 Vergleiche, einer Bitmap mit 2.4 MPixel, und einer CPU-Frequenz von 3.4GHz ergibt sich ein Gewinn von
1242/478*2.4M/3.4G*4*1000 = 7.3 ms.
Bei einer Laufzeit von 63 ms für die Umwandlung der Bitmap ist der Gewinn von 7 ms nicht unbedeutend.

Delphi-Quellcode:
var
   Data:Array[0..366+111] of Integer;
Delphi-Quellcode:
procedure TestCMovShort;
const HI=High(Data);
asm
               push esi // Save ESI
               push 0 // Memory
               mov esi,255 // Max-Value
               mov ecx,HI // Index from High(Data) downto 0
@Loop: mov edx,[ecx*4+Data] // Value
               mov eax,0 // Min-Value
               cmp edx,esi // Value vs. Max-Value
               cmovg eax,esi // Load Max-Value if Value > Max-Value
               cmovbe eax,edx // Load Value if Value <= Max-Value
               mov [esp],al // Store New Value
               dec ecx // Index - 1
               jns @Loop // Loop until Index = 0
               pop ecx // Remove Memory from Stack
               pop esi // Restore ESI
end;
Delphi-Quellcode:
PROCEDURE TestMov;
const HI=High(Data);
asm
               push 0 // Memory
               mov ecx,HI // Index from High(Data) downto 0
@Loop: mov eax,[ecx*4+Data] // Value
               cmp eax,0 // Value vs. 0
               jle @Zero // Jump if New-Value <= 0
               cmp eax,255 // Value vs. 255
               jbe @Store // Jump if Value <= 255
               mov byte[esp],255 // Store 255 as New Value
               jmp @Next // Next Index
@Zero: mov byte[esp],0 // Store 0 as New Value
               jmp @Next // Next Index
@Store: mov [esp],al // Store New Value
@Next: dec ecx // Index - 1
               jns @Loop // Loop until Index < 0
               pop ecx // Remove Memory from Stack
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat