AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread GENAU alle 10ms ausführen

Ein Thema von Cubysoft · begonnen am 19. Aug 2015 · letzter Beitrag vom 23. Aug 2015
Antwort Antwort
Seite 1 von 3  1 23      
Cubysoft

Registriert seit: 5. Sep 2014
Ort: Ludwigshafen
76 Beiträge
 
Delphi XE8 Professional
 
#1

Thread GENAU alle 10ms ausführen

  Alt 19. Aug 2015, 21:46
Hallo,

Gleich vorab: ich kann Codebeispiele nur sehr schlecht posten, da ich im Ausland bin und hier nur mit dem Handy reinkomme.

Nun zu meiner Frage: ich programmiere derzeit ein kleines Spiel. Dabei soll eine Berechnung genau alle 10ms ausgeführt werden und das in einem anderen Thread. Bis jetzt habe ich einen Runner Thread der immer im Hintergrund läuft (was auch am besten so bleiben soll). Der ist so aufgebaut:

While true
CODEBLOCK
SLEEP (10)
*WHILE

Problem ist nun halt, dass die Berechnung hierbei stark von dem benutzten PC abhängt. Wenn der Codeblock bei schnelleren PCs 5ms braucht, braucht er bei langsamen vllt 10. Ich möchte aber dass der Thread immer 10 ms braucht. Und nicht wie bei dem Beispiel 15ms oder 20ms..

Habt ihr da eine Idee?
Tobias
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#2

AW: Thread GENAU alle 10ms ausführen

  Alt 19. Aug 2015, 23:07
mehrteilige Antwort:
1. egal wie "genau" Windows die 10ms einhält, wenn dein Code länger wie 10ms braucht, wird das nix... da dann nur schnellerer PC, weniger machen, besser programmieren
2. als Timer/RunnerThread wäre minimal sinnvoll "while(not Terminated) do begin Sleep(10); SetEvent(xxx); end;"
3. als WorkerThread(s) wäre minimal sinnvoll "while(not Terminated) do begin WaitForEvent(xxx,TimeOut); if not "TimeOut" then CallWorkProc; end;"

Timer/RunnerThread der ja "nur" SetEvent macht kann "HighestPriority" laufen. WorkerThread kann "HigherPriority" laufen. Wenn ein ThreadPool an Workerthreads und eine MehrkernCPU, dann dürfte eine Ausführung sogar mal notfalls etwas länger wie 10ms dauern, weil ja ein anderer Kern den nächsten TimerEvent übernimmt und noch teils "halbparallel" ausführt.

Das sind aber alles keine Aufgaben, welche eine Usermode Delphi Anwendung so hart zeitkritisch bearbeiten sollte, dann lieber ein eigener Treiber per DDK im Kernelmode und es wird realistisch beherrschbar.
Ich definiere das Timing von Threads lieber so: es dauert alle "mindestens" solange wie da angegeben(also hier immer mindestens 10ms), es kann aber auch "länger" dauern.

Per HighPrecisionTimerMode kommt man so wie oben kurz beschrieben mit aktueller Hardware und Win7..10 durchaus auf +/-5ms Genauigkeit... also man könnte 10..15ms zu 98% erreichen. Aller neueste Systeme gehen auch 5msec +/-2 wenn man ohne IO Treiber Nutzung nur im Ram arbeitet... aber da ist Windows im UserMode dann wirklich am Ende dessen, was mit sinnvollem Aufwand an zu 98% "quasi garantierten" Zeiten möglich ist.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#3

AW: Thread GENAU alle 10ms ausführen

  Alt 19. Aug 2015, 23:11
dann lieber ein eigener Treiber per DDK im Kernelmode und es wird realistisch beherrschbar.
Echt jetzt - für ein Spiel? Ich würde eher sagen, daß die Architektur des Spiels nochmal überdacht werden sollte, damit sie nicht so zeitkritisch ist.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 04:12
While true
CODEBLOCK
SLEEP (10)
*WHILE
Da braucht jeder Schleifendurchlauf mindestens 10ms!
Was genau willst Du eigentlich erreichen? Ich tippe auf Bildaufbau mit 100 Hz?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 07:29
neben der Problematik, das du es so eh nicht hinbekommt, GENAU alle 10ms etwas auszuführen (wg. 'Sleep'), kann man bei längeren Intervallen durchaus so vorgehen:
Delphi-Quellcode:
while true do begin
  start := GetTickCount;
  DoSomething();
  Elapsed := GetTickCount - start;
  if Elapsed < TotalWaitingTime then Sleep (TotalWaitingTime - Elapsed);
end;
Du wartest also 'TotalWaitingTime' abzüglich der für den Berechnungsvorgang benötigten Zeit. Du kannst aber nicht davon ausgehen, das 'DoSomething' immer in exakt gleichen Intervallen aufgerufen wird. Kann ja sein, dass das OS kurz einen Schluckauf hat.

Daher musst Du deine Berechnungen (Zeitabhängige Bewegungen, schätze ich mal) so ausführen, das Du nicht das 'konstante' Intervall berücksichtigst, sondern die Differenz zwischen letzter Berechnung und jetzt. Dann laggt das Spiel zwar vielleicht immer noch, aber wenigstens sind die Bewegungen gleichförmig.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 08:11
Dabei muss man aber beachten, dass Windows nur bedingt echtzeitfähig ist.
Markus Kinzler
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#7

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 08:22
Zitat:
dann lieber ein eigener Treiber per DDK im Kernelmode und es wird realistisch beherrschbar.
Da würde ich schon eher so ein fertiges Realtime-System einsetzen, das sollte es auch hinbekommen.
http://www.kithara.de/de/produkte/realtime-suite
Ob sich das einfach installieren lässt weiss ich nicht, es scheint sich tief in den Unterbau von HAL einzuklinken, und dein Windows ist womöglich nicht mehr das was es mal war.

Aber wie schon zuvor gesagt: Für ein Spiel ???

Könnte aber sein das manche Spiele soetwas nutzen ?


Rollo
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 08:47
Und warum sollte man keinen Timer nehmen?

Code:
function timeSetEvent; external mmsyst name 'timeSetEvent';
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#9

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 08:53
Da würde ich schon eher so ein fertiges Realtime-System einsetzen, das sollte es auch hinbekommen.
http://www.kithara.de/de/produkte/realtime-suite
Für zeitkritische Steuerungsaufgaben (PLC, CNC) ist das schon ein wirklich gutes Produkt. Allerdings nehmen die Herrschaften auch Lizenzgebühren pro Installation, die locker mit dem Preis für die meisten "großen" PC-Spiele mithalten können. Ich wage deshalb mal die Behauptung, daß kein PC-Spiel diese Engine einsetzt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#10

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 10:22
Idealerweise verzichtet man heutzutage auf feste Framerates. Man misst man die Zeit des letzten Schrittes und berechnet quasi, was in der Zeit passiert ist.
Wenn ein festes Zeitraster aus technischen Gründen für dein Spiel wirklich nötig ist, dann kannst du das von der Ausgabe entkoppeln (die vermutlich die meiste Zeit frisst). Nur wenn noch Zeit ist oder eine bestimmte Zielframerate unterschritten wird, kann ein neues Bild gerendert werden.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz