Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mo Jul 07, 2025 19:16

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 19 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
BeitragVerfasst: Sa Okt 01, 2011 15:52 
Offline
DGL Member

Registriert: So Jul 24, 2011 15:40
Beiträge: 15
Hi,
folgendes Problem. Das kleine Spielchen an dem ich grad bastle, ist sehr rechen-unintensiv. Bei wenig zu berechnenden Objekten erziele ich teilw. Frameraten von über 2000. Auf manchen Rechnern, auf denen ich es getestet habe war die FPS-Zahl sogar noch höher.

Als Framelimiter habe ich diese Prozedur aus dem DGL-Wiki eingebaut http://wiki.delphigl.com/index.php/Frameratenbegrenzung .. läuft soweit auch prima. Leider nur, sofern die Berechnungszeit eines Frames nicht zu kurz war, dann wird es scheinbar ungenau. Ich habe als Übergabewert sogar schon Extended anstatt Double verwendet um die Berechnung noch genauer zu haben. Aber selbst das scheint nicht auszureichen. Das Spiel läuft also mitunter zu langsam - weil es zu schnell läuft :shock:

Ich hatte mir sogar schon überlegt eine Schleife zu schreiben, die lediglich dafür sorgt, dass die CPU genug zu tun hat, damit die Framezeit nicht zu klein wird - aber das scheint mir irgendwie idiotisch ;D

Hat da jemand vielleicht eine bessere Idee?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Okt 01, 2011 16:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Was benutzt du zur Ermittlung der Zeit? GetTickCount ist nicht genau genug. Du müsstest den PerformanceCounter nehmen bzw unter Linux clock_gettime mit der Realtime-Clock (siehe dazu die entsprechende Manpage).

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Okt 01, 2011 18:14 
Offline
DGL Member

Registriert: So Jul 24, 2011 15:40
Beiträge: 15
Das ist es ja. Ich benutze den PerformanceCounter schon:

pseudocode:
Code:
  1.  
  2. var
  3.  Freq, StartCount, EndCount: Int64;
  4.  frametime: Extended;
  5. begin
  6.  
  7. QueryPerformanceCounter(StartCount);
  8.  
  9.    Logic;
  10.    Render;
  11.    //...
  12.  
  13. QueryPerformanceCounter(EndCount);
  14.  
  15. frametime := (((EndCount - StartCount) / Freq) * 1000);
  16.  
  17. LIMIT_FPS(frametime + FLastSleep);


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Okt 01, 2011 19:41 
Offline
DGL Member

Registriert: Do Jun 28, 2007 17:58
Beiträge: 193
Programmiersprache: Pascal, C
Sleep wird vermutlich zu ungenau sein - hat je nach Windows-Version nur eine Auflösung von ca. 20ms

_________________
http://audorra.sourceforge.net//http://andorra.sourceforge.net


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Okt 02, 2011 03:33 
Offline
DGL Member

Registriert: So Jul 24, 2011 15:40
Beiträge: 15
Hättest du eine Idee was man da machen kann?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Okt 02, 2011 09:48 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Adory12345 hat geschrieben:
Hättest du eine Idee was man da machen kann?


Ersetzte Sleep durch nen eigenes Sleep das ne While schleife und den Performance Counter nutzt.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Okt 02, 2011 10:09 
Offline
DGL Member

Registriert: Di Sep 07, 2010 14:28
Beiträge: 34
Wohnort: Frankfurt
Programmiersprache: C++,C#,VB(,Delphi)
Hallo

Was auch noch wichtig ist, dass du nicht die Zeit, die du zum Zeichen brauchst misst, sondern die Zeit von einem Frame zum nächsten Frame misst.

Jonathan

_________________
Das mit dem Dx tut mir leid.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Okt 02, 2011 11:09 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Warum willst du überhaupt framelimiting machen? Am besten steigst du auf Timebased Movement um. Damit ist die Framerate egal, solange die Frequenz des Counters größer ist als die Framerate. Beim Performance-Counter liegt die Frequenz üblicherweise im sechs bis siebenstelligen Bereich ;).

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Okt 03, 2011 12:42 
Offline
DGL Member
Benutzeravatar

Registriert: So Sep 26, 2010 12:54
Beiträge: 238
Wohnort: wieder in Berlin
Programmiersprache: Englisch
... oder Du schaust Dir mal die Möglichkeiten an die es überhaupt gibt. Hilfreich für Dich, ist vielleicht diese Seite http://dewitters.koonsolo.com/gameloop.html.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Okt 05, 2011 00:34 
Offline
DGL Member

Registriert: So Jul 24, 2011 15:40
Beiträge: 15
Time-Based-Movement klingt zwar nach der perfekten Lösung, aber die letztliche Implementierung gestaltet dann leider doch nicht so einfach für jemanden wie mich :| Frame-Based-Movement macht alles so schön leicht. Habe es jetzt mit einer Sleep-Prozedur gelöst, die den QPC nutzt. Danke für eure Antworten! :wink:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Okt 05, 2011 08:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hast du dir unseren Wiki-Artikel durchgelesen?

Zeig zumindest mal deinen Sleep-Code her, denn wenn du's nicht sauber löst, frisst dir das deine ganze CPU-Zeit weg.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Okt 05, 2011 14:09 
Offline
DGL Member

Registriert: So Jul 24, 2011 15:40
Beiträge: 15
Stimmt schon, die CPU läuft seitdem auf hochtouren ;)

Framelimiter:
Code:
  1. procedure LIMIT_FPS(atd: Extended);
  2. var
  3.   sleeptime: Extended;
  4. begin
  5.   sleeptime := 1000 / MaxFramerate - (atd - FLastSleep);
  6.   if sleeptime > 0 then
  7.   begin
  8.     SleepQPC(trunc(sleeptime));     //vormals Sleep(trunc(sleeptime));
  9.  
  10.     FLastSleep := sleeptime;
  11.   end
  12.   else
  13.     FLastSleep := 0;
  14. end;
  15.  


SleepQPC:
Code:
  1.  
  2. procedure SleepQPC(t: cardinal);
  3. var a, b: Int64;
  4. Begin
  5.     QueryPerformanceFrequency(b);
  6.     QueryPerformanceCounter(a);
  7.     b := a + (b * t) div 1000;
  8.     While a < b do QueryPerformanceCounter(a);
  9. end;
  10.  


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Okt 05, 2011 15:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Nichts für ungut. Aber beim Lesen dieses Themas habe ich irgendwie Schmerzen auf der rechten hinteren Seiten meines Kopfes bekommen. :twisted:

Meiner Meinung nach bringt Frameraten begrenzen nur etwas, wenn man nicht unnötig die komplette CPU/GPU belegen will. Was also wohl in recht vielen Anwendungen vorteile mit sich bringen kann. Egal ob man Frameraten begrenzt oder nicht. Sobald man flüssige Animationen darstellen will benötigt man immer Time Based Movement. Die beiden Sachen schließen sich aber keineswegs aus oder ersetzen den jeweils Anderen.

Ein eigenes Sleep, was nichts anderes macht als BusyWaiting (100% CPU-Last), ist Schrott. Dann kann man solch ein Sleep auch gleich lassen. Den einzigen Fall wo ich so etwas akzeptieren würde sind Echtzeitanwendungen die genau einen Zeitpunkt abpassen müssen. Was hier aber nicht der Fall sein dürfte.

Genug gemäcker. Sleep ist kein richtiges Warten. Sondern es übergibt die Ausführung an den TaskSheduler von Windows für mindesten die angegeben Zeit. Nach oben hin kann durchaus Luft sein. Sobald dein Rechner mit anderen Sachen stark beschäftigt ist kann das deutlich länger dauern. Und es kann eine Mindestauflösung von ca. 16ms haben. Das kann man per API Befehl auch beeinflussen. Kann mir nie merken wie der heißt. Wenn ich das richtig sehe, dann verlässt sich der Code aus dem Wiki darauf, dass das Sleep genau so lange wartet wie es theoretisch sollte.

Es sollte ausreichen, wenn du für deine Berechnung nicht nur die Zeit berücksichtigst die du für das reine Rendern benötigst hast, sondern du musst die Zeit zwischen zwei Frame berücksichtigen. Sleep kann länger dauern oder du kannst in deiner Anwendung ja selber Sachen machen die nicht direkt zum Rendern gehören. Aber all das kann deine Anwendung ausbremsen. Und wenn du das beim Warten nicht berücksichtigst, dann rutscht dir die Zeit unter deiner Berechnung durch und wird zu jedem Frame dazu gerechnet. Indirekt. Und dadurch wirkt deine Anwendung langsamer als sie sollte. Für TBM bräuchtest du sowieso die richtige FPS und nicht nur die Zeit fürs reine Rendern.

Ein Begrenzen der FPS auf 30 wird wegen der Tolleranz von Sleep allerdings immer geringer ausfallen. Also es werden immer weniger FPS als gewollt. Von daher lieber mal ein paar FPS anpeilen mehr. Falls das Sleep zu klein werden sollte kann das aber auch zu unschönen Effekten führen. Wenn du nur 1-2 ms warten willst er aber jedes mal 16 warten würde. Aber dafür müsste das Rendern des Bildes schon einige Millisekunden in anspruch nehmen.

Alternativ kann man auch in einem OnTimer rendern. Für normale Anwendungen ist das wohl okay. Für Spiele eher nicht. Auf 30ms eingestellt und gemessen wie viel Zeit tatsächlich zwischen den OnTimer Events liegt und schon hat man die Zeit die zwischen zwei Bildern liegt. Die kann man dann für das TBM verwenden. Um das Begrenzen der Framerate bräuchte man sich dann nicht direkt kümmern. Sollte aber ein Menü offen sein oder das Fenstr verschoben werden werden Timer Events ausgesetzt.

Ich denke also das Hauptproblem liegt nicht im Sleep ansich sondern auf dem blinden Vertrauen darauf und der ungenügenden Messung der Zeiten. Das eben "Blindzeiten" nicht mit erfasst werden und somit nicht mit berechnet werden.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 06, 2011 07:12 
Offline
DGL Member
Benutzeravatar

Registriert: So Sep 26, 2010 12:54
Beiträge: 238
Wohnort: wieder in Berlin
Programmiersprache: Englisch
Solange er nichts zeitkritisches schreibt, wird es in seinem Fall wohl ausreichen, Sleep zu verwenden....


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 06, 2011 07:58 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Die ungenauigkeit von Sleep ist nicht zu unterschätzen. Vorallem in Spielen merkt man es dann doch irgendwie, der Zeitfluss wirkt unkontinuierlich, wenn man Pech hat, funkt einem das bei schnelleren Stellen gehörig in den Plan. Das macht ein Spiel dann „irgendwie komisch“ oder „blöd, weil es irgendwie unlogisch ist“ (sowas hört man öfter über kleinere Spiele mit solchen oder ähnlichen Macken).

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 19 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]