Funktion optimieren

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

hazumu-kun

Betreff: Funktion optimieren

BeitragSo, Okt 03, 2010 15:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Community,

Heute habe ich meine wireworld Sandbox nochmal angeschaut und etwas erweitert.
Nun wollte ich die CPU Last senken und habe mir anzeigen lassen welche Funktion am meisten Zeit benötigt.

Das Ergebnis zeigte, dass Draw_World() 50ms benötigt, im Gegensatz zu Update_Input() und Draw_HUD() (beide ca. 1ms).

Ich bin aber momentan ratlos wie ich folgenden Code noch weiter optimieren könnte:

BlitzBasic: [AUSKLAPPEN]

Function Draw_World ()
; Projects the data from world(x,y,0) to the canvas
Local x,y

For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
Color 0,0,COLOR_FIELD(world(x,y,0))
Rect 240+x*10,y*10,10,10,1
Next
Next
End Function


Hier der gesamte Code:
BlitzBasic: [AUSKLAPPEN]

; ###### Viken Emesh's Wireworld implementation
; ### Date: 27.03.2010 - 00.00.0000
; ******

;[Block] #### Constants
Const FIELD_EMPTY = 0
Const FIELD_WIRE = 1
Const FIELD_FRONT = 2

Const WORLD_SIZEX = 80
Const WORLD_SIZEY = 80
Const FIELD_TAIL = 3

Dim COLOR_FIELD(3)
COLOR_FIELD (FIELD_EMPTY) = $000000
COLOR_FIELD (FIELD_WIRE) = $DDDD00
COLOR_FIELD (FIELD_FRONT) = $0000DD
COLOR_FIELD (FIELD_TAIL) = $DD0000

Dim FIELD_TEXT$(3)
FIELD_TEXT$ (FIELD_EMPTY) = "Empty cell"
FIELD_TEXT$ (FIELD_WIRE) = "Wire cell"
FIELD_TEXT$ (FIELD_FRONT) = "Electron front"
FIELD_TEXT$ (FIELD_TAIL) = "Electron tail"

Const FPS= 30

Const ERROR_TIMEOUT= 2000
;[End] ****

;[Block] #### Variables
Dim world(WORLD_SIZEX-1,WORLD_SIZEY-1,1)
Local fps_timer

Global sel_ctype= 0
Global mx, my

Global error_active
Global error_time

Global img_hud
;[End] ****

;[Block] #### Initialization
AppTitle "Viken Emesh's Wireworld implementation"
Graphics 240+10*WORLD_SIZEX,10*WORLD_SIZEY,0,2
SetBuffer BackBuffer()

fps_timer= CreateTimer (FPS)

img_hud= CreateImage (240,10*WORLD_SIZEY)

PreDraw_HUD()
;[End] ****

;[Block] #### Mainloop
While Not KeyHit(1)
ms= MilliSecs()
Draw_HUD()
ms_Draw_HUD= MilliSecs()-ms

ms= MilliSecs()
Draw_World()
ms_Draw_world= MilliSecs()-ms

ms= MilliSecs()
Update_Input()
ms_Update_Input= MilliSecs()-ms

Color 255,255,0
Text 5,300,"Draw_Hud() : "+ms_Draw_HUD+"ms"
Text 5,310,"Draw_world() : "+ms_Draw_World+"ms"
Text 5,320,"Update_Input(): "+ms_Update_Input+"ms"

Flip 0
Cls
WaitTimer (fps_timer)
Wend
;[End] ****

End

; #### Functions
Function Update_Input()
; Processes input
sel_ctype= sel_ctype+Sgn(MouseZSpeed())
If sel_ctype<0 Then sel_ctype=0
If sel_ctype>3 Then sel_ctype=3

mx= MouseX():my=MouseY()

If mx>240 And mx<240+WORLD_SIZEX*10 Then
If my>0 And my<WORLD_SIZEY*10 Then
Color 0,0,COLOR_FIELD(sel_ctype)
Rect mx/10*10,my/10*10,10,10,1

If MouseDown(1) Or MouseHit(1) Then
If sel_ctype= FIELD_FRONT Or sel_ctype= FIELD_TAIL Then
If world((mx-240)/10,my/10,0)<> FIELD_EMPTY Then
world((mx-240)/10,my/10,0)=sel_ctype
Else
error_active= 1
error_time= MilliSecs()
EndIf
Else
world((mx-240)/10,my/10,0)=sel_ctype
EndIf
EndIf
EndIf
EndIf

If KeyDown(57) Then ;Space
NextGen()
Delay 50
EndIf
If KeyHit(211) Then ;DEL
World_Clear()
EndIf
If KeyHit(199) Then ;HOME
World_Reset()
EndIf

End Function

Function PreDraw_HUD()
; Draws the information display
SetBuffer ImageBuffer(img_hud)

Color 255,255,255
Line 239,0,239,10*WORLD_SIZEY

Text 5,5,"Welcome to Wireworld!"
Text 5,30,"[Scroll] : select cell-type"

Text 5,45,"[L-Click]: place cell"

Rect 24,64,12,12,0

Text 5, 85,"[Space] : calculate next"
Text 5, 95," generation"

Text 5,110,"[DEL] : reset world"
Text 5,125,"[HOME] : reset electrons"

Flip
SetBuffer BackBuffer()
End Function

Function Draw_HUD()
DrawImage img_hud,0,0


Color 0,0,COLOR_FIELD(sel_ctype)
Rect 25,65,10,10,1

Color 255,255,255
Text 40,65,FIELD_TEXT$(sel_ctype)

If error_active Then
Color 255,0,0
Text 5,150,"Electron front/tail only"
Text 5,160,"on wire or another electron!"
If error_time+ERROR_TIMEOUT<MilliSecs() Then
error_active=0
EndIf
EndIf
End Function

Function Draw_World ()
; Projects the data from world(x,y,0) to the canvas
Local x,y

For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
Color 0,0,COLOR_FIELD(world(x,y,0))
Rect 240+x*10,y*10,10,10,1
Next
Next
End Function

Function NextGen()
; Calculates the next generation of wireworld cells
Local x,y
Local x2,y2
Local count

For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
Select world(x,y,0)
Case FIELD_EMPTY
world(x,y,1)= 0
Case FIELD_WIRE
count=0
; Check surrounding cells for electron fronts
For x2= x-1 To x+1
For y2= y-1 To y+1
If x2=>0 And x2<= WORLD_SIZEX-1 And y2=>0 And y2<= WORLD_SIZEY-1 Then
If world(x2,y2,0)= FIELD_FRONT Then count= count+1
EndIf
Next
Next
If count=1 Or count=2 Then
world(x,y,1)= FIELD_FRONT
Else
world(x,y,1)= FIELD_WIRE
EndIf
Case FIELD_FRONT
world(x,y,1)=FIELD_TAIL
Case FIELD_TAIL
world(x,y,1)=FIELD_WIRE
End Select
Next
Next

; Copy values from world(x,y,1) to world(x,y,0)
For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
world(x,y,0)=world(x,y,1)
Next
Next
End Function

Function World_Clear()
Local x,y
For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
world(x,y,0)=0
world(x,y,1)=0
Next
Next
End Function

Function World_Reset()
Local x,y
For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
If world(x,y,0)=FIELD_TAIL Or world(x,y,0)=FIELD_FRONT Then
world(x,y,0)=FIELD_WIRE
EndIf
Next
Next
End Function
; ****


Als nächstes wäre dann die Funktion NextGen dran, die pro Durchlauf auch in etwas 50ms verschluckt.

Irgendwelche Vorschläge wie ich noch ein paar Millisekunden rauskitzeln kann?
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

Thunder

BeitragSo, Okt 03, 2010 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Probier Mal:
BlitzBasic: [AUSKLAPPEN]
Function Draw_World ()
; Projects the data from world(x,y,0) to the canvas
Local x,y

For x= 0 To WORLD_SIZEX-1
For y= 0 To WORLD_SIZEY-1
Color 0,0,COLOR_FIELD(world(x,y,0))
If COLOR_FIELD(world(x,y,0))<>0 Then Rect 240+x*10,y*10,10,10,1
Next
Next
End Function

Das hat die Zeit bei mir drastisch gesenkt.

mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

hazumu-kun

BeitragSo, Okt 03, 2010 15:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, das macht die Sache doch nun deutlich schneller.
Allerdings verwundert mich nun die ~75% Cpu Auslastung die ich mit 30fps auf meiner 2GHz Maschine erzeuge.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

Thunder

BeitragSo, Okt 03, 2010 15:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Komisch, bei mir hat es nur 3-4%. (Debugmodus?)

Windows XP 32 Bit Service Pack 2
Intel Celeron-M 1,5 GHz
2048 MiB RAM
Intel Grafik

mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

hazumu-kun

BeitragSo, Okt 03, 2010 15:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Nope kein Debugmodus.

WinXP 32-SP3
ATI Radeon 9200SE
2048MB Ram
AMD Athlon XP 2400+ 2,02GHz

EDIT:
Beim Auskommentieren von
BlitzBasic: [AUSKLAPPEN]

Flip 0
Cls

in der Hauptschleife komm ich auf ca 3-5%, was ist hier los?
Seid wann haut Flip so rein?
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

mpmxyz

BeitragSo, Okt 03, 2010 22:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hatte dieses Verhalten einmal in BlitzMax gesehen.
Ich vermute, dass es entsteht, weil die Zeichenanweisungen nicht sofort von der Grafikkarte ausgeführt werden (können), sondern zwischengespeichert werden.
Beim Flip muss aber alles gezeichnet sein.
Daher wird vor dem eigentlichen "Flip" alles fertiggezeichnet.
So sieht meine Vermutung aus.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Holzchopf

Meisterpacker

BeitragMo, Okt 04, 2010 12:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Es könnte auch sein, dass hazumu-kun bei seinem Grafikkartentreiber "force sync on" eingestellt hat (ich glaube, die meisten Treiber-Interfaces nennen das erzwungene synchrone Flippen von Front- und Backbuffer so). Das käme dann einem Flip 1 gleich. Und wie wir wissen, ist Flip 1 nicht gerade CPU-schonend.

Also: Hazumu, hast du diese Einstellung bei dir etwa vorgenommen? Dann schalte den Sync mal, wenn möglich, auf Application Standard oder dann halt ganz aus. Vielleicht hilft das ja.

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

hazumu-kun

BeitragMo, Okt 04, 2010 15:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab die Einstellung für VSync auf immer aus gestellt, keine Verbesserung.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group