![]() |
AW: Thread GENAU alle 10ms ausführen
Zitat:
Zitat:
|
AW: Thread GENAU alle 10ms ausführen
Zitat:
Oder mal ne For-Schleife die 1 Minute läuft? Hast Du mal ein anderes Programm gestartet (Word Delphi oder so...) |
AW: Thread GENAU alle 10ms ausführen
Windows ist nun mal kein Echtzeitbetriebssystem.
Entweder ich kann mich auf die Timings der Betriebssystem zu 100% verlassen; dann kann ich meine Algorithmen so auslegen, dass ich von einem exakt akkuraten Timing ausgehe. Bei Airbags oder diversen Industriemaschinen ist das notwendig. Der Airbag muss genau dann auslösen wann ich das will und nicht irgendwie 6,8ms früher oder später. Das ist Kompromisslos und auch der Grund warum Airbags zum Glück nicht von einem Windows gesteuert werden. Oder die Timings meines Betriebssystems sind unzuverlässig. Sobald ich eine Abweichung habe, kann ich meine Logik nicht mehr auf ein exaktes Timing basieren lassen. In einem Spiel beispielsweise muss ich mir dann eine andere Methode suchen, um zeitdiskrete Berechnung auszuführen. Jede Millisekunde, seien es auch nur 6,8ms, sind zuviel und machen meine Logik kaputt. Wenn ich davon ausgehe 25 Frames in der Sekunde zu haben und stur in jedem 25. Frame 100 Punkte auf den Score addiere, dann ist das Spiel unfair und kaputt. Auch wenn Multimedia-Timer bessere Qualitäten haben als der Standardtimer sind sie nun mal nicht perfekt. Und solange ich kein perfektes Timing habe, muss ich bei der Programmierung davon ausgehen, dass das Timing vollkommen kaputt ist. Nur so kann ich zuverlässige Algorithmen bauen. (Btw, was die 6,8ms angeht. Lass mal ein Spiel oder ein Benchmark oder etwas anderes sehr rechenlastiges währenddessen laufen.) |
AW: Thread GENAU alle 10ms ausführen
Zitat:
Auszug, ohne Anspruch auf Vollständigkeit, eben nur mal schnell zum Testen:
Delphi-Quellcode:
implementation uses MMSystem; const MW_TIMER_TEST = WM_USER + 100; procedure TimerCallBackProc(uTimerID, uMsg: Integer; dwUser, dwParam1, dwParam2: LongWord); stdcall; begin PostThreadMessage(HWND(dwUser), MW_TIMER_TEST, 0, 0); end; procedure TFrmTimerTest.Start; const MaxCount = 10000; var TimerMsg: TMsg; TimerProc: TTimerProc; TimerInterval, TimerID, TimerCount, Counter: Integer; CloseRequested: boolean; TimerReturnMsg: Longbool; begin Counter := 0; TimerInterval := 10; TimerCount := 0; TimerProc := TimerCallBackProc; TimerID := timeSetEvent(TimerInterval, TimerInterval, @TimerProc, GetCurrentThreadId, TIME_PERIODIC); if TimerID = 0 then begin timeEndPeriod(TimerInterval); Exit; end; Memo.Lines.Clear; edStartTickCount.Tag := GetTickCount; edStartTickCount.Text := IntToStr(edStartTickCount.Tag); repeat TimerReturnMsg := GetMessage(TimerMsg, 0, 0, 0); Inc(Counter); if Counter > MaxCount then break; if TimerMsg.Message = MW_TIMER_TEST then begin Inc(TimerCount); // Anzeige, damit der VCL-Thread auch ein bisserl was zu tun hat Memo.Lines.Add('Count:'+IntToSTr(TimerCount)); end; TranslateMessage(TimerMsg); DispatchMessage(TimerMsg); until (integer(TimerReturnMsg) <= 0); edStopTickCount.Tag := GetTickCount; edStopTickCount.Text := IntToStr(edStopTickCount.Tag); edDiffTickCount.Tag := edStopTickCount.Tag - edStartTickCount.Tag; edDiffTickCount.Text := IntToStr(edDiffTickCount.Tag); timeKillEvent(TimerID); timeEndPeriod(TimerInterval); end; |
AW: Thread GENAU alle 10ms ausführen
Zitat:
Bei alten PCs passierte es noch öfter, dass die Musik aussetzt, wenn man die CPU zu sehr beanspruchte. Heute passiert das kaum mehr, allerdings bemerkt man diesen Puffer noch, falls es mal zu einem Bluescreen kommen sollte. Noch heute wiederholt mein PC die letzte Sekunde des aktuellen Songs dann in einer Endlosschleife. Die Lösung des Problem ist also der Puffer in der Soundkarte. Nicht (nur) der Multimedia-Timer. |
AW: Thread GENAU alle 10ms ausführen
Um ein laufendes Video zum Stottern zu bringen, genügt es meiner Erfahrung nach bereits, neben dem Zugriff auf die Festplatte durch den Videoplayer ein oder zwei weitere Zugriffe auf dieselbe Festplatte anzuleiern, z.B. einen Kopier- und ein Entpackungsvorgang. Auch Midi-Files stottern beim Abspielen, wenn man gleichzeitig weitere Zugriffe auf dieselbe Platte hat. Das hat mit der Rechenpower im Grunde nichts zu tun, sondern ist dem "Flaschenhals" Festplatte geschuldet. Beim Video kommt es natürlich, wie oben bereits erwähnt, auf den Videopuffer an, aber auch auf die Video-Auflösung, denn je höher die Auflösung, desto mehr Daten fallen pro Sekunde an.
|
AW: Thread GENAU alle 10ms ausführen
Zitat:
|
AW: Thread GENAU alle 10ms ausführen
Da sonst mit Puffern gearbeitet wird, spielt das eh keine Rolle.
Es geht ja auch darum, dass das mit der Echtzeitfähigkeit nicht so richtig funktioniert, wenn während des Abspielens ein anderer Prozess am werkeln ist. Nochmal: Windows ist nicht realtimefähig und daher kann man sich nun einmal nicht darauf verlassen, das irgend ein Timer immer perfekt auslöst. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz