Seite 3 von 3

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 21:07
von STARGÅTE
SilverSurfer hat geschrieben:Und 1 bis zwei Millisekunden in zwei Zeilen Code wäre schon Krass viel, oder nicht?
Das hat ja nichts mit der Anzahl der Codezeilen dazwischen zu tun.
ElapsedMilliseconds() an sich muss ja "irgendwo" die Zeit messen bzw. auslesen.
Dieses "messen" kann natürlich nicht in jedem einzelnen Takt gemacht werden, sondern nur sporadisch, um nicht den normalen Code zu bremsen.
Somit aktualisiert sich der Wert also irgendwann zwischen zwei Aufrufen und das nicht mal um +1 ms sonden durchaus bis zu mehrere Millisekunden !! wenn andere "wichtigere" Sachen dazwischen kommen.
Hier ein Beispielcode dafür, wo ich direkt hintereinander ElapsedMilliseconds() aufrufe, und nebenbei den Prozessor beschäftige.

Code: Alles auswählen

Procedure Nichts(Void)
	Protected I = 0
	Repeat
		I + 1
	ForEver
EndProcedure

Define N
For N = 1 To 4
	CreateThread(@Nichts(), 0)
Next

For N = 1 To 100000
	Old = ElapsedMilliseconds()
	New = ElapsedMilliseconds()
	If Old <> New
		Debug "+"+Str(New-Old)+"ms"
	EndIf
Next
+1ms
+1ms
+1ms
+1ms
+1ms
+6ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+34ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+1ms
+34ms
+1ms
[...]

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 21:20
von NicTheQuick
@ts-soft:
Hier ging es nirgendwo um Zeitmessungen. Wenn du dir den Code genauer angeschaut hättest, hättest du das auch gemerkt. Von daher ist es hier kein Problem das ganze mit Debugger laufen zu lassen.

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 21:26
von Helle
Ich wette, SilverSurfer benutzt eine ältere PB-Version, die ElapsedMilliseconds() noch mit ca.15.6ms auflöst und nicht wie neuere Versionen mit 1ms. Mit PB4.60 (habe ich gerade noch) ergeben sich die 5.5s.

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 22:06
von SilverSurfer
Ich benutze PureBasic 5.11

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 22:25
von Helle
Ich weiß jetzt nicht, ab welcher Version das geändert wurde.
Einfacher Test:

Code: Alles auswählen

For i = 0 To 199
  Debug ElapsedMilliseconds()
  Delay(1)
Next
Zeigt bei 5.31 Abstände im Einer-Bereich an; bei älteren Versionen 15 bis 16. Damit sind natürlich keine 22ms auflösbar, nur 16 (15), 32 (31) usw.

Re: ElapsedMilliseconds() Problem ?

Verfasst: 12.07.2015 22:35
von SilverSurfer
Tatsache, auch bei 5.11 gibt es diese Unterschiede von 16 ms. Boh, da kann ich ja lange basteln...lach. Vielen Dank Helle..... :-)

Re: ElapsedMilliseconds() Problem ?

Verfasst: 13.07.2015 08:54
von Rings
eventuell doch einmal updaten.

Mich wundert immer warum leute noch mit so alten versionen Fehler melden
und nicht einmal neuere Version vorher testen.

Re: ElapsedMilliseconds() Problem ?

Verfasst: 13.07.2015 11:51
von SilverSurfer
@Rings: Ich mache das aus lauter Bosheit, um euch zu beschäftigen..... :bounce:

Re: ElapsedMilliseconds() Problem ?

Verfasst: 13.07.2015 16:03
von Vera
Helle hat geschrieben:Ich weiß jetzt nicht, ab welcher Version das geändert wurde.
Tja, das muß dann wohl noch vor PB 4.31 gewesen sein, denn bei mir sind es auch hauptsächlich 1ms Differenzwerte. ... oder betrifft es am Ende nur WIN ? 8)

Ebenso braucht bei mir das Beispiel mit den zwei ElapsedMilliseconds() Aufrufen mit oder ohne Debugger ~ 39xx und die 'verbesserte' Version dann auch knapp > 40xx.

Nichtsdestotroz ... ich hab mal gesucht und nirgendwo einen leisesten Hinweis gefunden, daß an ElapsedMilliseconds() etwas geändert wurde, dafür aber bei einer BoardSuche nach "+ElapsedMilliseconds +16ms" einige interessante Threads gefunden. Daraus ein paar Zitate:

In: Billiges Game-Timing mit nativen PB-Mitteln - 13.08.2008
Kaeru Gaman hat geschrieben:wie auch in dem Artikel beschrieben wird:
10ms ist die tatsächliche höchstgenauigkeit eines unjustierten* GetTickCount, und damit auch von Elapsedmilliseconds.
wenn man dann mit nativen PB-Mitteln nachmisst, dann kommt man drauf,
dass die genauigkeit im Mittel um die 13ms liegt.
das kann bis zu 15/16 ms hochgehen,
In: important! ElapsedMilliseconds() - Jan 19, 2008
PB hat geschrieben:ElapsedMilliseconds() is a wrapper for the GetTickCount_() API, that's all.
Kaeru Gaman hat geschrieben:... the native ElapsedMilliseconds is already 1ms precise.
about Linux-API... the 16ms gap is a Windows timeslice problem.
Scheinbar liegt doch das Problem eher beim Betriebsystem und vielleicht bei der Hardware und CPU ... aber das überlasse ich lieber denen, die in dieser Materie drin stecken :mrgreen:

PS: danke für einen aufschlußreichen Allgemeine-Frage-Thread :-)

Re: ElapsedMilliseconds() Problem ?

Verfasst: 28.07.2015 21:44
von Helle
Ich habe nur Windows am Start (die RasPis lasse ich mal außen vor :mrgreen: ), aber die Vielfalt an Möglichkeiten mit ElapsedMilliseconds() Unfug zu treiben ist schon gewaltig. Je nach OS-Version und Hardware kann man verschiedenste Auflösungen erhalten. Kurze History: Eine der ersten für PCs einheitliche Zeitbasis war die NTSC-Trägerfrequenz für die Farbdifferenz-Signale (NTSC=amerikanische Farbfernseh-Norm). Diese Frequenz beträgt 3.579545MHz und wird als Power Management Timer = PMTIMER bezeichnet. Ein Drittel davon, nämlich 1.193182 MHz, wurde auch verwendet und nennt sich Programmable Interval Timer = PIT. Dann kam der HPET (High Precision Event Timer) mit der Frequenz 14.31818MHz = 4*3.579545 (s.o.). All dies ließ aber viel Spielraum für den tatsächlichen Einsatz. Und als auch die Prozis noch die Fähigkeit des Runtertaktens im Ruhe-Modus erhielten, war auch die CPU-Taktfrequenz als Zeitbasis dahin (s.div.ältere Code-Beispiele). Aber glücklicherweise waren sich AMD und Intel mal einig und haben den invariant TSC (TSC = Time Stamp Counter) etabliert. Idee: In der CPU läuft ein Zeitgeber, der unabhängig von CPU-States ist und so eine wesentlich genauere Zeitbasis liefert als die oben genannten.
Intel schreibt dazu:
"The invariant TSC will run at a constant rate in all ACPI P-, C-, and T-states. This is the architectural behavior moving forward. On processors with invariant TSC support, the OS may use the TSC for wall clock timer services (instead of ACPI or HPET timers). TSC reads are much more efficient and do not incur the overhead associated with a ring transition or access to a platform resource."
AMD schreibt:
"TscInvariant: The TSC rate is ensured to be invariant across all P-States, C-States, and stop grant transitions (such as STPCLK Throttling); therefore the TSC is suitable for use as a source of time."
Ob die CPU invariant TSC beherrscht kann mit CPUID 80000007H, EDX Bit8 überprüft werden.
Also: Wer wirklich vergleichbare Messungen/Timings (mit nicht allzu alten Prozis) machen will, sollte sich diesen Weg mit invariant TSC mal anschauen. Die benötigte Nominal-CPU-Frequenz lässt sich zur Not mittels QueryPerformanceFrequency_() ermitteln. Wäre mal wieder was für "Tipps & Tricks"...

In diesem Sinne
Helle