Seite 2 von 3

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:02
von NicTheQuick
Es geht dabei nicht um Unzuverlässigkeit, sondern darum wie du programmierst. Das folgende Schnipsel wird dir jede Sekunde eine Ausgabe im Debug-Fenster geben. Gleichzeitig verbrauchst du dabei 100% CPU-Last, was nicht gut ist.

Code: Alles auswählen

nextPrint = ElapsedMilliseconds() + 1000

count = 0

Repeat
	If ElapsedMilliseconds() >= nextPrint
		nextPrint + 1000
		Debug "Event!"
		count + 1
	EndIf
Until count = 10
Ein kleines Delay(10) in der Schleife würde die CPU-Last drastisch reduzieren, aber dann kann es passieren, dass der Body vom If nicht rechtzeitig ausgeführt wird, sondern bis zu 10 ms zu spät.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:10
von Bisonte
Und um noch ein wenig Verwirrung zu streuen ;) ....
Sollte man darauf achten, dass TimerEvents niemals nicht für "exakte" Zeitmessungen genommen werden sollten.

Wenn zum Beispiel ein Fenster mal heftig viele Events, sagen wir einem Thread der Daten zu einem Gadget schickt,
bekommt, dann wird das TimerEvent natürlich "obenauf" in die Warteschlange der Events abzuarbeiten hat gelegt.
Und schon sind es nicht mehr 1000ms sondern vielleicht 1009ms oder gar noch mehr.... oder der Klassiker :
der User bewegt das Fenster .... Ich meine auch irgendwo im Forum gelesen zu haben, dass der WindowsTimer/ElapsedMilliseconds()
von Haus aus mit Zeiten unter 50ms Probleme hat, diese korrekt einzuhalten.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:17
von RSBasic
Bisonte hat geschrieben:Wenn zum Beispiel ein Fenster mal heftig viele Events [...] dann wird das TimerEvent natürlich "obenauf" in die Warteschlange der Events abzuarbeiten hat gelegt.
Und schon sind es nicht mehr 1000ms sondern vielleicht 1009ms
Das stimmt. Kommt drauf an, ob diese kleine Verzögerung überhaupt ein Problem ist. In den meisten Fällen eher nicht, aber falls doch, dann muss man eine andere Variante nehmen.
Bisonte hat geschrieben:der Klassiker : der User bewegt das Fenster
Das stimmt. Dafür gibt es zum Glück BindEvent, was natürlich meiner Meinung nach sogar die bessere Wahl ist, wenn man mit Events arbeiten möchte.
Beispielcode:

Code: Alles auswählen

EnableExplicit

Procedure Timer()
  Select EventTimer()
    Case 1
      Debug "Timer-Event wird jede Sekunde ausgelöst."
  EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  AddWindowTimer(0, 1, 1000)
  
  BindEvent(#PB_Event_Timer, @Timer())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:22
von Josh
Bisonte hat geschrieben:Ich meine auch irgendwo im Forum gelesen zu haben, dass der WindowsTimer/ElapsedMilliseconds() von Haus aus mit Zeiten unter 50ms Probleme hat, diese korrekt einzuhalten.
Bei ElapsedMilliseconds() war das zumindest früher so. Da hast du in Windows Rückgabewerte nur in 32ms (ich glaube zumindest, dass es 32 waren) Schritten bekommen. Vor ca. 1-2 Jahren hat Fred intern auf einen anderen Timer umgestellt, seit dem kann ElapsedMilliseconds() viel genauer sein.

Seit dieser Umstellung beginnt der ElapsedMilliseconds() auch mit 0, früher mit irgendeinem unbestimmten Wert.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:27
von diceman
NicTheQuick hat geschrieben:Es geht dabei nicht um Unzuverlässigkeit, sondern darum wie du programmierst. Das folgende Schnipsel wird dir jede Sekunde eine Ausgabe im Debug-Fenster geben. Gleichzeitig verbrauchst du dabei 100% CPU-Last, was nicht gut ist.

Code: Alles auswählen

nextPrint = ElapsedMilliseconds() + 1000

count = 0

Repeat
	If ElapsedMilliseconds() >= nextPrint
		nextPrint + 1000
		Debug "Event!"
		count + 1
	EndIf
Until count = 10
Ein kleines Delay(10) in der Schleife würde die CPU-Last drastisch reduzieren, aber dann kann es passieren, dass der Body vom If nicht rechtzeitig ausgeführt wird, sondern bis zu 10 ms zu spät.
Also wenn ich genau diesen Schnipsel ausführe, steigt meine CPU-Auslastung nicht über 12%. :? Mit Delay(1) bleibt sie allerdings relativ konstant beim Default-Wert.
Wüßte ich gerne mehr darüber, also welche Möglichkeiten mir prinzipiell offenstehen so etwas zu vermeiden. Der optionale Parameter "FlipMode" beim OpenScreen()-Befehl verhindert das ja auch, oder?

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 16:29
von RSBasic
RSBasic hat geschrieben:Unter Windows wird soweit ich weiß die Zeit in Millisekunden seit dem Windows-Start zurückgegeben
Diese Aussage muss ich zurücknehmen. Das war mal so. Es wurde in der Tat geändert und es beginnt neuerdings immer mit 0.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 17:58
von Fluid Byte
Hatten das Thema letztens erst: http://www.purebasic.fr/german/viewtopi ... 7&start=14
Remarks hat geschrieben:The absolute value returned is of no use since it varies depending on the operating system. Instead, this function should be used to calculate time differences between multiple ElapsedMilliseconds() calls.

This function is relatively accurate: it may have a slight variation, depending on which operating system it is executed on, this is due to the fact that some systems have a lower timer resolution than others.
Fazit, die Ergebnisse sind unterschiedlich denn sie sind BETRIEBSSYSTEM-ABHÄNGIG.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 18:04
von edel
diceman hat geschrieben:
NicTheQuick hat geschrieben:Es geht dabei nicht um Unzuverlässigkeit, sondern darum wie du programmierst. Das folgende Schnipsel wird dir jede Sekunde eine Ausgabe im Debug-Fenster geben. Gleichzeitig verbrauchst du dabei 100% CPU-Last, was nicht gut ist.

Code: Alles auswählen

nextPrint = ElapsedMilliseconds() + 1000

count = 0

Repeat
	If ElapsedMilliseconds() >= nextPrint
		nextPrint + 1000
		Debug "Event!"
		count + 1
	EndIf
Until count = 10
Ein kleines Delay(10) in der Schleife würde die CPU-Last drastisch reduzieren, aber dann kann es passieren, dass der Body vom If nicht rechtzeitig ausgeführt wird, sondern bis zu 10 ms zu spät.
Also wenn ich genau diesen Schnipsel ausführe, steigt meine CPU-Auslastung nicht über 12%. :? Mit Delay(1) bleibt sie allerdings relativ konstant beim Default-Wert.
Bei 8 Kernen hast du eine Auslastung von etwa 12%. Das heisst das einer der Kerne gerade auf 100% laeuft.

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 08.02.2018 18:25
von diceman
:o Ooops, Danke! :bluescreen:

Re: Frage zur genauen Funktionsweise von ElapsedMilliseconds

Verfasst: 09.02.2018 11:10
von dige
Sehe gerade, dass ElapsedMilliseconds() beim ersten Aufruf mit 0 Initialisiert wird und dann kontinuierlich hochzählt.
Bisher hatte man immer die Zeit seit dem Windows Start übermittelt bekommen, als Long, der dann nach 24 Tagen
(> 2147483647 ms) plötzlich ein Vorzeichen bekam :lol: böse Programmierfalle und nun endlich behoben :allright: