Seite 1 von 2

Schneller ClearScreen-Befehl

Verfasst: 09.03.2006 12:56
von Sven
Der ClearScreen(R, G, B)-Befehl ist - zumindest auf meinem Rechner ;-) - ziemlich langsam. Mag sein, dass es am Rechner liegt, aber den Hintergrund eines Sprites von Bildschirmgröße mit Box(...) schwärzen geht etwa 10 mal schneller als der ClearScreen auf dem Bildschirm, ich hätte es nun gerade andersrum vermutet.

Woran liegt es, dass ClearScreen() so lahm ist?

Gibt es einen schnelleren Befehl, wenn ich den Hintergrund nicht mit RGB füllen, sondern einfach nur schwarz haben will?

Sven

Verfasst: 09.03.2006 15:08
von KeyKon
Ich hab immer einfach ein schwarzes (oder wie ichs grad brauch) Sprite zur Hand...

KeyKon

Verfasst: 09.03.2006 16:27
von Zaphod
wie hast du denn gemessen? hast du beachtet, dass man beim bildschirm geschwindigkeitseinschränkungen durch die framerate hat (mit mehr als der framerate kann man halt nicht den screen updaten)?

Verfasst: 09.03.2006 17:13
von Sven
Ich hab zum Messen die Mikrosekunden nach und vor dem Befehl subtrahiert. Hab aber festgestellt, dass zwar das Box() sehr schnell ist (wenige 10µs), dafür aber das StopDrawing() in etwa solange braucht wie das ClearScreen().

Mit dem schwarzen Sprite hab ich auch schon überlegt, aber zum einen muss das dann so groß wie der Screen sein, zum anderen muss ich mal sehen, wielange das nötige DisplaySprite() dann wieder benötigt. Werd ich mal probieren.

Sven

Verfasst: 09.03.2006 17:20
von KTX82
Habe mal schnell ein kleines Tool zur Messung geschrieben, welche Methode schneller ist und dabei kam heraus, das Clearscreen definitiv der schnellste ist. Der nächst langsamere ist Box und der langsamste Sprite.

Hier die Messergebnisse auf meinem System (Geforce3 AGP 4x):

Code: Alles auswählen

;               Alle Angaben in Millisekunden je 10000 Aufrufe
;-----------------------------------------------------------------------------
;
;          |          - 32 Bit -            |          - 16 Bit -            |
;          |                                |                                |
;          | 800x600 | 1024x768 | 1280x1024 | 800x600 | 1024x768 | 1280x1024 |
;----------+---------+----------+-----------+---------+----------+-----------|
;CLS + RGB | 2516    | 4188     | 7109      | 1219    | 2031     | 3453      |
;CLS       | 2437    | 4062     | 7297      | 1187    | 1953     | 3360      |
;Sprite    | 7328    | 12125    | 21235     | 3562    | 5844     | 10015     |
;Sprite3D  | 6156    | 9906     | 16578     | 6141    | 10078    | 16485     |
;Box + RGB | 4375    | 7204     | 11157     | 3532    | 4297     | 6141      |
;Box       | 3719    | 6015     | 10172     | 2109    | 3125     | 5219      |
;----------+---------+----------+-----------+---------+----------+-----------|
um es selbst zu probieren hier das kleine Tool (erstellt mit PB4b5 - läuft nicht auf 3.94 !)
Aber vorsicht, unter umständen kann ein Testdurchlauf ziemlich Zeit in Anspruch nehmen je nach Einstellung der Konstanten am Anfang (Auflösung und Farbtiefe) und System auf dem es läuft. Am Ende zeigt das Programm alle Messergebnisse in Millisekunden an - mit ESC beenden.

Code: Alles auswählen

If InitSprite() = 0 Or InitSprite3D() = 0 Or InitKeyboard() = 0 : End : EndIf


#ktx_resX = 1024
#ktx_resY = 768
#ktx_bits = 32


OpenScreen(#ktx_resX, #ktx_resY, #ktx_bits, "Test")

color.l = RGB(0,0,0)
CreateSprite(0, #ktx_resX, #ktx_resY, 0)
CreateSprite(1, 4, 4, #PB_Sprite_Texture)
CreateSprite3D(1, 1)

If StartDrawing(SpriteOutput(0))
  Box(0, 0, #ktx_resX, #ktx_resY, color)
  StopDrawing()
EndIf
If StartDrawing(SpriteOutput(1))
  Box(0, 0, 4, 4, color)
  StopDrawing()
EndIf


If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Clearscreen + RGB-Farbbefehl...")
  StopDrawing()
EndIf
FlipBuffers()


ms_a1 = ElapsedMilliseconds()
For i = 1 To 10000
  ClearScreen(RGB(0,0,0))
Next
ms_a2 = ElapsedMilliseconds()
ms_a = ms_a2 - ms_a1


If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Clearscreen + Farbvariable...")
  StopDrawing()
EndIf
FlipBuffers()


ms_b1 = ElapsedMilliseconds()
For i = 1 To 10000
  ClearScreen(color)
Next
ms_b2 = ElapsedMilliseconds()
ms_b = ms_b2 - ms_b1


If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Sprite...")
  StopDrawing()
EndIf
FlipBuffers()


ms_c1 = ElapsedMilliseconds()
For i = 1 To 10000
  DisplaySprite(0, 0, 0)
Next
ms_c2 = ElapsedMilliseconds()
ms_c = ms_c2 - ms_c1


If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Sprite3D...")
  StopDrawing()
EndIf
FlipBuffers()


ms_d1 = ElapsedMilliseconds()
For i = 1 To 10000
  Start3D()
    ZoomSprite3D(1, #ktx_resX, #ktx_resY)
    DisplaySprite3D(1, 0, 0)
  Stop3D()
Next
ms_d2 = ElapsedMilliseconds()
ms_d = ms_d2 - ms_d1


ClearScreen(RGB(0,0,0))
If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Box + RGB-Farbbefehl...")
  StopDrawing()
EndIf
FlipBuffers()


ms_e1 = ElapsedMilliseconds()
For i = 1 To 10000
  StartDrawing(ScreenOutput())
    Box(0, 0, #ktx_resX, #ktx_resY, RGB(0,0,0))
  StopDrawing()
Next
ms_e2 = ElapsedMilliseconds()
ms_e = ms_e2 - ms_e1


ClearScreen(RGB(0,0,0))
If StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10, 10, "Box + Farbvariable...")
  StopDrawing()
EndIf
FlipBuffers()


ms_f1 = ElapsedMilliseconds()
For i = 1 To 10000
  StartDrawing(ScreenOutput())
    Box(0, 0, #ktx_resX, #ktx_resY, color)
  StopDrawing()
Next
ms_f2 = ElapsedMilliseconds()
ms_f = ms_f2 - ms_f1


text1$ = "Clearscreen + RGB-Farbbefehl: " + Str(ms_a)
text2$ = "Clearscreen + Farbvarialbe: " + Str(ms_b)
text3$ = "Sprite: " + Str(ms_c)
text4$ = "Sprite3D: " + Str(ms_d)
text5$ = "Box + RGB-Farbbefehl: " + Str(ms_e)
text6$ = "Box + Farbvariable: " + Str(ms_f)


Repeat
  ClearScreen(RGB(0,0,0))
  
  If StartDrawing(ScreenOutput())
    FrontColor(RGB(255,255,255))
    DrawingMode(1)
    DrawText(10, 10, text1$)
    DrawText(10, 30, text2$)
    DrawText(10, 50, text3$)
    DrawText(10, 70, text4$)
    DrawText(10, 90, text5$)
    DrawText(10, 110, text6$)
    StopDrawing()
  EndIf

  FlipBuffers()

  ExamineKeyboard()
Until KeyboardReleased(#PB_Key_Escape)

Verfasst: 09.03.2006 18:09
von Moskito
Also ich würde empfehlen anstatt ElapsedMilliseconds() doch lieber den wesentlich genaueren Befehl TimeGetTime_() zu verwenden.
Ansonsten habt ihr in euren Benchmarks immer ca 5 MS "Luft".



bis denne
Thomas


Komisch, bei meinen Tests die ich im Februar gemacht habe, war Clearscreen wesentlich langsamer als ein 1024x768 Sprite. Aber ich habe die Tests auch mit PB 3.94 gemacht. Vielleicht sind die GDI Befehle ja mittlerweile flotter geworden....

Verfasst: 09.03.2006 18:18
von NicTheQuick
[c]ClearScreen()[/c] ist kein GDI-Befehl, deswegen heißt es ja
auch "Screen" und nicht "Image" oder sowas.

Verfasst: 09.03.2006 18:21
von Moskito
Stimmt, hab ich auch grad nachgelesen. Tja , das kommt davon wenn ich solche Befehle nicht mehr benutze.

Verfasst: 09.03.2006 20:20
von KTX82
Moskito hat geschrieben:Also ich würde empfehlen anstatt ElapsedMilliseconds() doch lieber den wesentlich genaueren Befehl TimeGetTime_() zu verwenden.
Ansonsten habt ihr in euren Benchmarks immer ca 5 MS "Luft".
Selbst damit würde denke ich keine "genaue" Messung zustande kommen können, es sein denn man setzt die Priorität des Programms auf RealTime, so das dazwischen keine anderen im Hintergrund laufenden Anwendungen pfuschen. Und extra um eventuelle Verzögerung durch den Zeitnahmebefehl irrelevant zu machen, habe ich gleich 10000 Aufrufe gemacht statt nur 1000, dass diese den Größten Teil der Zeit ausmachen., so spiegelt es doch schon annähernd das Resultat dar.

@Sven: Poste mal deine Ergebnisse und teste mit verschiedenen Auflösungen und Farbtiefen, weil es kann doch nicht angehen das Sprite wirklich so viel schneller sein soll bei dir.

Verfasst: 10.03.2006 00:44
von Moskito
Selbst damit würde denke ich keine "genaue" Messung zustande kommen können
...Na dann würde ich das an deiner Stelle mal ausprobieren...
Bei mir liegen die Abweichungen (wenn überhaupt) bei 1 - 2 Millisecs, was vermutlich an der Festplatte liegt, die den Source nach dem Compilieren mal wieder abspeichert. Einfach jeden Benchmark 3x wiederholen. Dann wirst du schon sehen wie genau diese Methode ist. Am besten verwendest du beide Abfragen zum testen mal simultan,(also elaspedmilliseconds und timegettime zusammen) dann siehst du auch die 5 MS Abweichung sofort.


bis denne
Thomas