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

Aktuelle Zeit: Mi Jul 16, 2025 16:01

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Zeitmessung im OnIdle
BeitragVerfasst: So Jun 08, 2008 09:17 
Offline
DGL Member

Registriert: So Aug 06, 2006 08:48
Beiträge: 91
Hallo,

auf einigen Systemen kam es bei meinem Schachprogramm zu einem Problem mit der Zeitmessung für das Timebased Movement: So stoppte die Drehung, die das Feld im "Menu-Modus" macht, sobald der Mauszeiger über dem Programmfenster war. Inzwischen weiß ich dass Idle weiterhin aufgerufen (und das Bild gerendert) wird, nur die gemessene Zeit so kurz ist, dass sich praktisch nichts bewegt. Das Idle-Event schaut so aus:
Code:
  1. //==============================================================================
  2. // IdleHandler
  3. //==============================================================================
  4. procedure TForm_Main.IdleHandler(Sender: TObject; var Done: Boolean);
  5. var
  6.   QPCStartCount, QPCEndCount : Int64;
  7. begin
  8.   Done := false;
  9.  
  10.   QueryPerformanceCounter(QPCStartCount);
  11.   //QPCStartCount := GetTickCount;
  12.   Render;
  13.   SwapBuffers(DC);
  14.   QueryPerformanceCounter(QPCEndCount);
  15.   //QPCEndCount := GetTickCount;
  16.  
  17.   DrawTime := (QPCEndCount - QPCStartCount) / PerfCounterFreq * 1000;
  18.   //DrawTime := (QPCEndCount - QPCStartCount);
  19.  
  20.   TimeCount := TimeCount + DrawTime;
  21.   Inc(FrameCounter);
  22.  
  23.   if TimeCount >= 250 then
  24.   begin
  25.     Caption := 'Schach - dkS  (' + FloatToStr(Round((1000 / DrawTime) * 100)
  26.       / 100) + 'fps, ' + FloatToStr(Round(DrawTime * 100) / 100) + 'mspf, ' +
  27.       IntToStr(FrameCounter) + 'fs) ';
  28.     ErrorHandler;
  29.     TimeCount := 0;
  30.   end;
  31. end;
Wie man sieht habe ich statt dem Hardwarecounter auch mal GetTickCount verwendet, da eine Idee war, dass der Fehler nur auf DualCores auftritt. Allerdings macht es nach meinem Ergebnis keinen Unterschied ob QPC oder TickCount.

Ich habe, da mir die o.g. Zeitmessung sowieso nicht zusagt eine zweite Methode ausprobiert:
Code:
  1. Done := false;
  2.  
  3.   QueryPerformanceCounter(QPCNow);
  4.   DrawTime := (QPCNow - QPCLastRender) / PerfCounterFreq * 1000;
  5.   Render;
  6.   SwapBuffers(DC);
  7.   QueryPerformanceCounter(QPCLastRender);
  8.  
  9.   TimeCount := TimeCount + DrawTime;
  10.   Inc(FrameCounter);
  11.  
  12.   if TimeCount >= 250 then
  13.   begin
  14.     Caption := 'Schach - dkS  (' + FloatToStr(Round((1000 / DrawTime) * 100)
  15.       / 100) + 'fps, ' + FloatToStr(Round(DrawTime * 100) / 100) + 'mspf, ' +
  16.       IntToStr(FrameCounter) + 'fs) ';
  17.     ErrorHandler;
  18.     TimeCount := 0;
  19.   end;
Diese verhält sich aber auch nicht anders, als die oben gezeigte. Ein zusätzliches Problem bei dieser Methode scheint zu sein, dass die OpenGL-Selektion nicht mehr funktioniert.

Ich habe daraufhin noch etwas mit der ersten Methode experimentiert, wobei mir aufgefallen ist, dass der Fehler manchmal behoben ist, wenn ich der Anwendung einen bestimmten Kern zuweise. Dann dreht sich das Feld manchmal normal, auch wenn der Zeiger über dem Feld ist - bewege ich ihn allerdings im Feld scheint das die Messung wieder zu beeinflussen, das Feld wird wieder langsamer.

Hat irgendjemand eine Idee was da schief laufen könnte?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 10:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Also ich habe das bei mir mit GetTickCount (bzw. Linux equivalenten) immer so gelöst, dass ich, wenn die differenz gleich 0 ist, den Frame geskippt und garnichts gemacht habe und auch die LastUpdate-Variable nicht verändert habe.

Gruß Lord Horazont

_________________
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  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 10:49 
Offline
DGL Member

Registriert: So Aug 06, 2006 08:48
Beiträge: 91
Naja, aber das ändert doch nichts daran, dass die Zeit falsch gemessen zu werden scheint, oder? Außerdem habe ich zumindest in der ersten variante ja keine LastUpdate-Variable. Was meinst du mit Frame skippen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 10:57 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Mach nur eine Messung pro Frame, und nimm die Differenz zum vorherigen. Dann solltest du die Zeitdifferenz jedoch auf jeden Fall nach oben deckeln, ich nehm z.B. ganz gerne 100ms dafür. Eine Deckelung nach unter, z.B. bei 5ms kann auch sinnvoll sein um Rechenleistung zu sparen, da >200fps kaum sinnvoll sind.
Wir haben dazu aber schon einige Threads hier.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 11:04 
Offline
DGL Member

Registriert: So Aug 06, 2006 08:48
Beiträge: 91
Ja, das wäre dann die zweite Variante - nur dass es bei der das selbe Messproblem gibt wie bei der ersten. Ein Framelimiter ist sowieso geplant, nur was soll ich machen wenn bei der Messung immer ~Null rauskommt?! Bisher bin ich der Meinung dass die Messung einfach falsch ist - auf anderen Systemen läufts ja richtig.
Was mir grade in den Sinn kommt - kann es sein dass EIST oder C1E da mit reinspielen? EDIT: Ne, ist vermutlich quatsch, GetTickCount geht ja auch nicht....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 11:13 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Du kannst dein Programm im Taskmanager auf einen Kern beschränken, das räumt zumindest diese Probleme aus.
Zeig mal deinen code wenn du nur einmal pro frame misst.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 11:20 
Offline
DGL Member

Registriert: So Aug 06, 2006 08:48
Beiträge: 91
Ich habe ja bereits oben geschrieben, dass das Beschränken auf einen Kern nicht hilft (das Problem zumindest nicht vollständig behebt). Die zwei Zeitmess-varianten stehen doch oben?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 11:27 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
ich seh da keine in der du nur einmal misst.
Ich mach das in etwa so:


Code:
  1.  
  2. var LastTick:int64;//global
  3.  
  4. procedure OnIdle
  5. var Now:int64;
  6.       DeltaT:real;
  7. begin
  8.   Done:=false;
  9.   Now:=QueryPerformanceCounter;
  10.   DeltaT:=(Now-LastRender)/Freqenz;
  11.   if DeltaT>0.1 then DeltaT:=0.1;
  12.   if DeltaT<=0.005 then
  13.    begin
  14.     sleep(1);
  15.     exit;
  16.    end;
  17.   LastTick:=Now;
  18.   Move(DeltaT);
  19.   Render;
  20. end;

_________________
Bild


Zuletzt geändert von The-Winner am So Jun 08, 2008 11:28, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Zeitmessung im OnIdle
BeitragVerfasst: So Jun 08, 2008 11:28 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Du misst effektiv nur die Zeit, die von QPCLastRender bis QPCNow vergeht, also die Zeit nach dem Rendern bis zum nächsten Rendern. Dass die so ganz grob 0 ist, erscheint mir logisch.
Probier mal statt
Code:
  1.   QueryPerformanceCounter(QPCLastRender);

das:
Code:
  1.   QPCLastRender := QPCNow;


Und für das seltsame FloatToStr-Konstrukt könntest du der Übersichtlichkeit halber auch FloatToStrF oder Format() mit %.2f verwenden.

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jun 08, 2008 13:15 
Offline
DGL Member

Registriert: So Aug 06, 2006 08:48
Beiträge: 91
Ahja bin ich doof, alles klar - jetzt geht's.^^ Jetzt tritt werden zwar die Selektionsmodelle nicht mehr angezeigt, wenn man auf ne Figur klickt, aber hinter den Fehler komme ich auch noch.^^
Vielen Dank!


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]