Bitte um Speed und crash test von meiner Lupen Funktion !!!!

Übersicht BlitzBasic BlitzPlus

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen

DAK

BeitragSo, Apr 20, 2014 23:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe leider nichts dazu gefunden, wie man Images aus Banks macht, aber ich habe mal einen Speed-Test zusammengestellt für alle Arten, wie man generierte Bilder auf den Schirm kriegt:

BlitzBasic: [AUSKLAPPEN]
writeCycles = Input("Writes: ")
drawsPerWrite = Input("Draws per write: ")

Graphics(800,600,32,2)

managedimage = CreateImage(800,600,1,1)
vramimage = CreateImage(800,600,1,2)
ramimage = CreateImage(800,600,1,4)


Write("Direct write test... ")

SetBuffer(FrontBuffer()) ;Uns interessiert ja nicht die Flip()-Speed

col = 0
startTime = MilliSecs()

For writes = 0 To writeCycles
For draws = 0 To drawsPerWrite
LockBuffer FrontBuffer()
For x = 0 To 800
For y = 0 To 600
WritePixelFast x,y,col
col = col + 1
Next
Next
UnlockBuffer FrontBuffer()
Next
Next

Print((MilliSecs()-startTime)+" ms")


Write("Draw from RAM test... ")

SetBuffer(ImageBuffer(ramimage))
startTime = MilliSecs()

For writes = 0 To writeCycles
LockBuffer ImageBuffer(ramimage)
For x = 0 To 799
For y = 0 To 599
WritePixelFast x,y,col
col = col + 1
Next
Next
UnlockBuffer ImageBuffer(ramimage)
SetBuffer(FrontBuffer())
For draws = 0 To drawsPerWrite
DrawBlock(ramimage,0,0)
Next
SetBuffer(ImageBuffer(ramimage))
Next

Print((MilliSecs()-startTime)+" ms")


Write("Draw from VRAM test... ")

SetBuffer(ImageBuffer(vramimage))
startTime = MilliSecs()

For writes = 0 To writeCycles
LockBuffer ImageBuffer(vramimage)
For x = 0 To 799
For y = 0 To 599
WritePixelFast x,y,col
col = col + 1
Next
Next
UnlockBuffer ImageBuffer(vramimage)
SetBuffer(FrontBuffer())
For draws = 0 To drawsPerWrite
DrawBlock(vramimage,0,0)
Next
SetBuffer(ImageBuffer(vramimage))
Next

Print((MilliSecs()-startTime)+" ms")


Write("Blit RAM to VRAM test... ")

SetBuffer(ImageBuffer(ramimage))
startTime = MilliSecs()

For writes = 0 To writeCycles
LockBuffer ImageBuffer(ramimage)
For x = 0 To 799
For y = 0 To 599
WritePixelFast x,y,col
col = col + 1
Next
Next
UnlockBuffer ImageBuffer(ramimage)
SetBuffer(ImageBuffer(vramimage))
DrawBlock(ramimage,0,0)
SetBuffer(FrontBuffer())
For draws = 0 To drawsPerWrite
DrawBlock(vramimage,0,0)
Next
SetBuffer(ImageBuffer(vramimage))
Next

Print((MilliSecs()-startTime)+" ms")


Write("Draw from Managed Image test... ")

SetBuffer(ImageBuffer(managedimage))
startTime = MilliSecs()

For writes = 0 To writeCycles
LockBuffer ImageBuffer(managedimage)
For x = 0 To 799
For y = 0 To 599
WritePixelFast x,y,col
col = col + 1
Next
Next
UnlockBuffer ImageBuffer(managedimage)
SetBuffer(FrontBuffer())
For draws = 0 To drawsPerWrite
DrawBlock(managedimage,0,0)
Next
SetBuffer(ImageBuffer(managedimage))
Next

Print((MilliSecs()-startTime)+" ms")

Print("")
Print("All tests done.")

WaitKey


Die Eingabeparameter sind:
"Writes": Wie viele Bilder neu erstellt werden.
"Draws per Write": Wie oft jedes dieser Bilder gezeichnet wird.

Damit kann man sowohl den Fall testen, dass es in jedem Frame eine Änderung gibt (wildes Herumgeschmiere) als auch dass das Bild eine längere Zeit gleich bleibt.


Zuerst mal zu den einzelnen Methoden:

-Direct Write: Jedes Pixel wird mittels WritePixelFast einzeln auf den Frontbuffer gezeichnet. Das Bild wird nicht zwischengespeichert. Jedes Mal wird das Bild neu auf den Frontbuffer gezeichnet. (Das ist das, was dein Programm momentan macht, nur mit dem Backbuffer, soweit ich verstehe).

-Draw from RAM: Das Bild wird mit WritePixelFast in ein Bild-Handle geschrieben, das sich im Scratch-Modus befindet (=das Bild liegt im RAM). Beim Zeichnen wird das Bild dann mit DrawBlock (um Masking zu verhindern) auf den Frontbuffer gezeichnet.

-Draw from VRAM: Gleich wie Draw from RAM, nur dass sich das Bild im Dynamic-Modus befindet, was heißt, dass das Bild im VRAM liegt.

-Blit RAM to VRAM: Zuerst wird das Bild in ein Scratch-Bild im RAM gezeichnet und das gesamte Bild wird dann in ein Dynamic-Bild im VRAM geschrieben (mittels DrawBlock). Beim Zeichnen wird das VRAM-Bild auf den Frontbuffer geschrieben

-Managed Image: So wie Draw from RAM, nur dass es sich um ein Bild im Managed-Mode handelt, das sowohl im RAM als auch im VRAM liegt.


Ich habe zwei verschiedene Tests auf beiden Grafikkarten laufen lassen. Der erste Test war 1 Write, 100 Draws per Write, also ein Bild wird erstellt und 100 Mal gezeichnet. Der zweite Test war 100 Writes, 1 Draw per Write, also 100 Bilder werden erstellt und je 1 Mal gezeichnet. Das sind die Ergebnisse:

Code: [AUSKLAPPEN]
1/100
Nvidia 635M:
-Direct Draw: 4615
-Draw from RAM: 796
-Draw from VRAM: 51
-Blit RAM to VRAM: 39
-Managed Image: 25
Intel HD 4000:
-Direct Draw: 6485
-Draw from RAM: 796
-Draw from VRAM: 84
-Blit RAM to VRAM: 65
-Managed Image: 40

100/1
Nvidia 635M:
-Direct Draw: 4636
-Draw from RAM: 1311
-Draw from VRAM: 2385
-Blit RAM to VRAM: 2839
-Managed Image: 1077
Intel HD 4000:
-Direct Draw: 6478
-Draw from RAM: 1305
-Draw from VRAM: 3302
-Blit RAM to VRAM: 3671
-Managed Image: 1005


Was als erstes auffällt ist, dass das direkte auf den Bildschirm malen mit Abstand die langsamste Lösung ist, selbst wenn sich das Bild jedes Frame ändert.

Das nächste ist, dass Draw from RAM auf beiden Karten fast genau gleich schnell ist. Das liegt daran, dass hier der Flaschenhals der RAM ist. Bei stark veränderlichen Bildern ist die RAM-Lösung recht gut, aber wenn das Bild längere Zeit (100 Frames sind bei Normalbetrieb knapp über 1.5 Sekunden) unverändert bleibt, dann ist es deutlich hinter den anderen Methoden.

Vom VRAM zeichnen ist sehr schnell, aber in den VRAM schreiben braucht leider seine Zeit, und davon nicht zu knapp. Diese Methode hilft nur wirklich, wenn das Bild länger unverändert bleibt.

In den RAM schreiben und den dann als Ganzes in den VRAM schieben rennt schneller als vom VRAM zeichnen, solange das Bild ein paar Frames gleich bleibt. Das sieht man in den Tests hier nicht, kann man aber ja recht leicht nachmachen. Ist aber bei Änderungen in jedem Frame ein Stück langsamer. Solange das aber nicht die Norm ist, rennt diese Methode bislang am Schnellsten.

All das wird allerdings hinfällig, sobald man zu den Managed-Bildern kommt. Die liegen sowohl im RAM als auch im VRAM (und verbrauchen somit ein wenig mehr Speicher). Es ist im Grunde eine native Implementierung von meinem Blit-Versuch und rennt verdammt schnell. Interessanterweise ist diese Methode sowohl dann am Schnellsten, wenn sich das Bild oft verändert, als auch dann, wenn es sich gar nicht verändert.

Mit denen solltest du dein Programm zwischen 5 und 500 mal schneller kriegen.
Ich habe auch einen Test laufen lassen, was passiert, wenn ich 1:1000 zeichnen lasse. Das ist ungefähr äquivalent dazu, dass der Nutzer ~17 Sekunden lang auf den Bildschirm schaut, ohne etwas zu verändern (kommt zumindest bei mir öfters mal vor).
Der Unterschied war dramatisch. In Direct Draw hat das Ding 46 Sekunden gebraucht. Vom RAM aus waren es noch 7.8 Sekunden, vom VRAM 776 ms, mit meinem Blitter 168 ms und mit einem Managed Image gerade mal 101 ms. Das ist ein Faktor von fast 500!
Gewinner der 6. und der 68. BlitzCodeCompo

Holzchopf

Meisterpacker

BeitragMo, Apr 21, 2014 0:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Bin jetzt zwar etwas spät, aber ich muss meinen Senf auch noch abgeben:

Wieso Read/WritePixelFast? Eine einfache Vergrösserung kriegt man auch mittels DrawImageRect hin. Nagut, eigentlich ist das einfache, was man damit hinkriegt, eine Streckung: Indem man 1px dicke Bildstreifen einfach wiederholt einzeichnet. Aber Exclamation Eine Vergrösserung ist nichts anderes als zwei mal Strecken Wink Also einmal in eine Richtung strecken, das Ergebnis zwischenspeichern und ebendieses noch in die andere Richtung gestreckt einzeichnen - voilà Cool

Hier ein Code, der zwar in Blitz2D geschrieben wurde, aber auf BlitzPlus übertragbar sein sollte. BlitzBasic: [AUSKLAPPEN]
Graphics 800,600, 0, 2
SetBuffer BackBuffer()

; zu zeichnendes Bild, vorzugsweise grösser als 600x600px
Local img% = LoadImage("D:\Bilder\BAC\bac83.jpg")

; hilfs-Bild und -Buffer für die Vergrösserung
; mittels DrawImageRect
Global imgZoom% = CreateImage(600,600)
Global imgbZoom% = ImageBuffer(imgZoom)

Local zoom% = 1 ; Vergrösserungsfaktor
Local timer% = CreateTimer(50) ; CPU-Bremse
Local grid% = False ; Raster ein/aus
Local rmethod% = 0 ; Render-Methode (DrawImageRect = 0, WritePixelFast = 1)

; Scancodes als Konstanten ablegen zwecks Lesbarkeit
Const KEY_ESCAPE% = 1
Const KEY_SPACE% = 57
Const KEY_G% = 34

; Hauptschleife
While Not KeyHit(KEY_ESCAPE)
; BackBuffer leeren, ganz wichtig!
Cls

; Vergrösserungsfaktor steuern (und auf 1...12 limitieren)
zoom = zoom +MouseZSpeed()
If zoom<1 Then zoom = 1
If zoom>12 Then zoom = 12

; Raster ein-/ausschalten
If KeyHit(KEY_G) Then grid = 1-grid
; Render-Methode wechseln
If KeyHit(KEY_SPACE) Then rmethod = 1-rmethod

; Bild vergrössert darstellen (inkl. Zeitmessung)
Local stime% = MilliSecs()
If rmethod=0 Then
DrawImageScaled(img, zoom, grid)
Else
DrawImageScaledPF(img, zoom, grid)
EndIf
; Zeitmessung beenden
Local etime% = MilliSecs()
Local ttime% = etime -stime

; Render-Infos ausgeben
Text 610,10, "render method [space]"
Text 610,30, rmethod

Text 610,60, "zoom [mousewheel]"
Text 610,80, zoom

Text 610,110, "grid [g]"
Text 610,130, grid

Text 610,160, "render time:"
Text 610,180, ttime+"ms"

; CPU ausbremsen und BackBuffer darstellen
WaitTimer(timer)
Flip 0
Wend
End

; Funktion zum Vergrössern eines Bildes mittels DrawImageRect
Function DrawImageScaled(pImg%, pScale%, pGrid%)
; keine Vergrösserung: Bildausschnitt direkt zeichnen
If pScale<=1 Then
DrawImageRect(pImg,0,0,0,0,600,600)
; Vergrösserung: Bild in zwei Schritten strecken
Else
; 1. Schritt: Bild horizontal strecken und in den Hilfsbuffer zeichnen
Local x%
Local ix%
Local ih% = 600/pScale+1
SetBuffer imgbZoom
Cls
; durch die gesamte Breite des Hilfsbuffers durchgehen
For x = 0 To 599
; und entsprechend positionierte Bildstreifen zeichnen
ix = x/pScale
; (ausser an Raster-Stellen)
If Not (pGrid=True And ((x+1) Mod pScale)=0) Then
; 1px breite Bildausschnitte in den Buffer zeichnen
DrawImageRect(pImg,x,0, ix,0, 1,ih)
EndIf
Next
; 2. Schritt: Hilfsbild vertikal strecken und auf den BackBuffer zeichnen
Local y%
Local iy%
SetBuffer BackBuffer()
; Vorgehen wie oben
For y = 0 To 599
iy = y/pScale
If Not (pGrid=True And ((y+1) Mod pScale)=0) Then
DrawImageRect(imgZoom, 0,y, 0,iy, 600,1)
EndIf
Next
EndIf
End Function

; Funktion zum Vergrössern eines Bildes mittels Write/ReadPixelFast
Function DrawImageScaledPF(pImg%, pScale%, pGrid%)
; keine Vergrösserung: Bildausschnitt direkt zeichnen
If pScale<=1 Then
DrawImageRect(pImg,0,0,0,0,600,600)
; Vergrösserung: Bild mittels Pixelwiederholung vergrössern
Else
; Ein- und Ausgabebuffer
Local bufRead% = ImageBuffer(pImg)
Local bufWrite% = BackBuffer()
; Ziel-Koordinate
Local x%,y%
; Bild-Koordinate
Local ix%,iy%
; Bild-Grenzen
Local iw% = ImageWidth(pImg)
Local ih% = ImageHeight(pImg)
; Farbwert
Local argb%
; Buffer sperren
LockBuffer bufRead
LockBuffer bufWrite
; Ziel-Grösse komplett durchgehen
For x=0 To 599
For y=0 To 599
; (ausser an Raster-Stellen)
If Not (pGrid=True And ((x+1) Mod pScale)=0) Then
If Not (pGrid=True And ((y+1) Mod pScale)=0) Then
; Bild-Koordinate berechnen
ix = x/pScale
iy = y/pScale
; und innerhalb der Grenzen: Pixel "kopieren"
If ix<iw And iy<ih Then
argb = ReadPixelFast(ix,iy, bufRead)
WritePixelFast(x,y,argb, bufWrite)
EndIf
EndIf
EndIf
Next
Next
; Buffer entsperren
UnlockBuffer bufRead
UnlockBuffer bufWrite
EndIf
End Function


Zugegeben: Die DrawPixelFast-Variante ist nicht optimiert. Aber ich behaupte jetzt mal, dass die mit allen möglichen Optimierungen nicht an die DrawImageRect-Variante heran kommt Rolling Eyes

MfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

Silbersurfer

BeitragMo, Apr 21, 2014 13:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Holzchopf
Zitat:
zugegeben: Die DrawPixelFast-Variante ist nicht optimiert. Aber ich behaupte jetzt mal, dass die mit allen möglichen Optimierungen nicht an die DrawImageRect-Variante heran kommt

Da gebe Ich dir recht, deine Variante ist schneller Rect draw 2 ms, meine lupe braucht 3-4 ms und deine Read/Write Variante 18 ms.
Eine Super Idee das ich da nicht selber drauf gekommen bin, danke Holzchopf für deinen wink mit dem Zaunpfahl Very Happy

Ich werde mal testen wie sich deine Variante in meinen Proggy macht

Dak
Zitat:
Ich habe leider nichts dazu gefunden, wie man Images aus Banks macht, aber ich habe mal einen Speed-Test zusammengestellt für alle Arten, wie man generierte Bilder auf den Schirm kriegt:

Entweder wieder mit Writepixel oder direkt im Speicher Poken habe dazu was im Englischen Forum gefunden
leider komm Ich damit nicht so klar, und das Demo gibt bei mir einen MAV

Zu deinen Speedtest. Bei mir ergaben diese
Code: [AUSKLAPPEN]
1/100
ATI HD6950:
-Direct Draw:      4207
-Draw from RAM:      277
-Draw from VRAM:   46
-Blit RAM to VRAM:   34
-Managed Image:      17
100/1
ATI HD6950:
-Direct Draw:      4209
-Draw from RAM:      732
-Draw from VRAM:   2088
-Blit RAM to VRAM:   2204
-Managed Image:      617


Also ist mit abstandt Holzchopf seine Variante am schnellsten
-------------------------------------------------------
XP 2000+ 512DDR Radeon 9800 XL 340GB HD
Hompage : http://home.arcor.de/silbersurfer01/
Is Bob engine http://home.arcor.de/silbersur.../Isbob.zip

DAK

BeitragMo, Apr 21, 2014 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Du must dabei bedenken, mein Speedtest misst (mit den gegebenen Einstellungen) die Zeit, die es braucht, 100 Mal zu zeichnen, wärend Holzchopfs Variante nur 1 Bild misst. Du musst sein Ergebnis also mal 100 rechnen, um es mit meinem Speedtest vergleichen zu können, oder meinen Speedtest mit 1/1 starten.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Silbersurfer

BeitragMi, Apr 23, 2014 10:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Edit So, nun habe ein keines Problem, ich bin jetzt bei der erstellung einer Undo Funktion.
Die ich in einer Bank angelegt habe soweit so gut. Nun habe ich das Undo auf 10 schritte begrenzt, sobald
die grenze erreicht ist, soll der erste eintrag in der Bank gelöscht werden und der rest der bank um einen zurück geschoben werden. Das wollte ich so erledigen
BlitzBasic: [AUSKLAPPEN]
If undopointer>9 FreeImage PeekInt(bank,0) : CopyBank bank,12,bank,0,108 :undopointer=undopointer-1

Komisch ist, alles klappt soweit nur das der vorletzte eintrag falsche werte hat(1-8) ok 9 falsch Question
was mache ich da falsch Bankgrösse ist 120 Byte schrittweite 12 Byte
Kann mir da Jemand einen Rat geben






Dak
Zitat:
Du must dabei bedenken, mein Speedtest misst (mit den gegebenen Einstellungen) die Zeit, die es braucht, 100 Mal zu zeichnen


Ja stimmt, aber anhand der ms sieht man das auch schon Dak, habe die art von Holzchopf jetzt übernommen
und auf mein Proggy Angepasst voilà nochmal 15-20% mehr leistung. An dieser Stelle ein dank an Holtzchopf

BlitzBasic: [AUSKLAPPEN]
Local startx%,starty%,writex%,writey%,counter%
Local endex%=posx%+ausschnittx%
Local endey%=ausschnitty%*lupenfactor

For Startx%=posx% To endex%
For writex%=counter% To counter%+lupenfactor-gitter-1
CopyRect startx%,posy%,1,ausschnitty,writex%,0 ,imageread,imagewrite
Next
counter%=counter%+lupenfactor
Next

counter%=0

For Starty%=0 To endey%
For writey%=counter% To counter%+lupenfactor-gitter-1
CopyRect 0,starty%,ausschnittx*lupenfactor,1,0,writey% , imagewrite,CanvasBuffer (lupenblatt)
Next
counter%=counter%+lupenfactor
Next


Durch diese Änderung kommen die Nvidia-Karten auch besser damit klar...
Nun kann Ich mich um andere sachen in meinen Proggy kümmern Danke Leute für die mithilfe
 

Silbersurfer

Betreff: So nun habe Ich alles Optimiert was ging

BeitragMi, Mai 07, 2014 3:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Habe jetzt, dank Holzchopf nochmal 15-20% mehr aus der Lupe rausholen können,
gleichzeitig habe Ich noch einiges wieder eingebaut, auf meinen Systemen ist damit flüssiges Arbeiten möglich.
Ich denke das es auf älteren Rechner nicht so gut laufen wird.

Hier nochmal der Aktuelle Download von BlitzPaint
http://home.arcor.de/silbersur...intneu.zip
user posted image

Der derzeitige Stand meines Proggys !

Arrow Werzeugleiste fertig, sind aber noch nicht alle werkzeuge eingebunden (noch in Arbeit)
Arrow Farbpalette ist auch fertig, werde aber noch mehre auswahlmöglichkeiten schaffen
Arrow Undo/Rendo funktion eingebaut, Ist in Moment auf 10 Schritte eingestellt
Arrow Pinsel auswahl fertig bis auf Brush (noch in Arbeit)

werkzeuge fertiggestelt !
Arrow Papierkorb
Arrow Freihand Malen
Arrow Lienen Malen
Arrow Keis Malen und ausgefüllt Malen
Arrow Ellipse Malen und ausgefüllt Malen
Arrow Rechteck Malen und ausgefüllt Malen
Arrow Undo/Rendo in max 10 schritten

was noch fehlt !
Arrow PolyLine ist in Arbeit
Arrow Bezier Line
Arrow Snap to Grid Funktion
Arrow filter für die Pinsel
Arrow Speicher funktion
Arrow Leinwand erstellen
Arrow und ein paar Bildfilter

Bevor jetzt die frage aufkommt warum Ich ein Malprogramm schreibe, es gibt ja schon so Viele und sicherlich viel leistungfähiger wie meines.
Der Grund ist, Ich wollte ein Simples und gut zu bediendes Malproggy schreiben womit man einfach Pixel kann, nichts mit Ebenen oder Layer alpha kanälen oder der gleichen.. Mein Proggy errinnert Stark an alte Amiga Zeiten alla D Paint, Personal Paint und Co und genau das soll auch so sein

Würde mich über anregungen und Kretik wie immer sehr Freuen
-------------------------------------------------------
XP 2000+ 512DDR Radeon 9800 XL 340GB HD
Hompage : http://home.arcor.de/silbersurfer01/
Is Bob engine http://home.arcor.de/silbersur.../Isbob.zip

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen


Übersicht BlitzBasic BlitzPlus

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group