Schneller ClearScreen-Befehl

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Sven
Beiträge: 374
Registriert: 23.09.2004 12:01

Schneller ClearScreen-Befehl

Beitrag 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
Benutzeravatar
KeyKon
Beiträge: 1412
Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM
PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM
Win10 x64 Home/Prof
PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:

Beitrag von KeyKon »

Ich hab immer einfach ein schwarzes (oder wie ichs grad brauch) Sprite zur Hand...

KeyKon
(\/) (°,,,°) (\/)
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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)?
Sven
Beiträge: 374
Registriert: 23.09.2004 12:01

Beitrag 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
KTX82
Beiträge: 95
Registriert: 31.08.2004 00:11
Wohnort: Mannheim
Kontaktdaten:

Beitrag 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)
Pharmacie populaire www.viagrasansordonnancefr.com aide aux malades
Benutzeravatar
Moskito
Beiträge: 182
Registriert: 18.01.2006 23:01
Kontaktdaten:

Beitrag 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....
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

[c]ClearScreen()[/c] ist kein GDI-Befehl, deswegen heißt es ja
auch "Screen" und nicht "Image" oder sowas.
Benutzeravatar
Moskito
Beiträge: 182
Registriert: 18.01.2006 23:01
Kontaktdaten:

Beitrag von Moskito »

Stimmt, hab ich auch grad nachgelesen. Tja , das kommt davon wenn ich solche Befehle nicht mehr benutze.
KTX82
Beiträge: 95
Registriert: 31.08.2004 00:11
Wohnort: Mannheim
Kontaktdaten:

Beitrag 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.
Pharmacie populaire www.viagrasansordonnancefr.com aide aux malades
Benutzeravatar
Moskito
Beiträge: 182
Registriert: 18.01.2006 23:01
Kontaktdaten:

Beitrag 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
Antworten