Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Exakte FPS (https://www.delphipraxis.net/115759-exakte-fps.html)

EWeiss 17. Jun 2008 15:43


Exakte FPS
 
berechne die FPS folgendermaßen

Delphi-Quellcode:
const
BB_FPS_AVERAGE_TIME = 500;
Delphi-Quellcode:

procedure GetFramesInSec;

begin

  BB_RenderTime := GetTickCount;
  BB_CurrentMilliSeconds := GetTickCount;

  BB_RenderTime := BB_CurrentMilliSeconds;
  if BB_FPSTime = 0 then   BB_FPSTime := BB_CurrentMilliSeconds;
  if BB_CurrentMilliSeconds - BB_FPSTime >= BB_FPS_AVERAGE_TIME then
    begin
      BB_FPS := BB_FPSCounter / (BB_CurrentMilliSeconds - BB_FPSTime) * 1000;
      BB_FPSTime := BB_CurrentMilliSeconds;
      BB_FPSCounter := 0;
    end;

  Inc(BB_FPSCounter);

end;
sind die berechneten Frames exakt oder nicht..
Meine Frage bezieht sich darauf das es ja verschiedene arten der berechnung von FPS gibt.
Was ist nun genau ?

EDIT:
Habe bei 1280x1024 die gleiche Frame anzahl wie in 320x240 .. 40 FPS:
Die Frames werden ermittelt in der RenderProc
Delphi-Quellcode:
    BbpPluginFunc(BassBoxInfo^);

    SongRender;
    GetFramesInSec;
    ProgressBarRender;

    // Refresh display
    if SwapBuffers(glDc) = True then
      Result := True;

    zUpdateWindow(glCtrl, Bool(0));
    ReleaseDC(glCtrl, glDc);
so wie man mir sagt sollen die Frames unter Vista extrem in den Keller fallen
kanns nicht testen hab kein Vista

gruss Emil

Medium 17. Jun 2008 16:03

Re: Exakte FPS
 
Die Frage ist, wie man hier "genau" definiert. Hält man sich exakt an den Wortlaut "Frames per Second", kann man nur rückblickend arbeiten, und schlicht nachzählen wie viele neue Frames in der letzten Sekunde erzeugt wurden. Wenn du möglichst zeitnah als "genau" betrachtest, wäre es sinnvoller die Zeit zu messen, die ein Frame braucht um komplett gerendert zu werden, und dieses dann auf eine Sekunde hochrechnest.
Ein Problem der letzten Variante ist, dass die Zeitdifferenz zwischen vor und nach dem Rendern bei einfachen Szenen so klein werden kann, dass man damit an die Grenzen der Messbarkeit auf einem PC kommt, und dadurch in der Hochrechnung dann ggf. größere Fehler in kauf nehmen muss. Dafür erhält man aber ein Maß, dass sich wirklich nur auf das zuletzt angezeigte Frame bezieht.

Das erste Verfahren kann man nun auch noch nach Belieben auf andere Zeiträume anwenden, und anschließens auf eine Sekundenbasis beziehen. Damit kann man dann zwischen "Zeitgenauigkeit" und "Fehlergenauigkeit" hin und her wandern. Andere Möglichkeiten sehe ich prinzipbedingt nicht. Im Extremfall zählt man die Anzahl aller Frames während einer kompletten Laufzeit, sowie die Sekunden die das Programm lief, dividiert diese durcheinander, und hat ein wahnsinnig exaktes Ergebnis. Leider aber erst nach Beendigung des Programmes, und ohne Information über die Verteilung. Der andere Extremfall ist der 2. o.g. Weg.

littleDave 17. Jun 2008 16:06

Re: Exakte FPS
 
Also wenn du es ganz genau haben willst würd ich dir QueryPerformanceCounter ans Herz legen, doch das ist für eine FPS-Berechnung etwas overkill. Die Genauigkeit von GetTickCount hat maximal 1ms, QueryPerformanceCounter hat (CPU-Abhängig) eine Genauigkeit von micro- bis nano-Sekunden. ABER: QueryPerformanceCounter einen Riesen nachteil: bei mehrkernigen Prozessoren kann das Ergebniss komplett falsch werden (KANN!!!). GetTickCount ist unabhängig von den CPUs und hat das Problem somit nicht (dafür halt das 42-Tage-Problem, das kommt aber weniger oft zum Vorschein).

Hier mal ein Beispiel-Template für QueryPerformanceCounter:
Delphi-Quellcode:
var
  iFrequency, iTimePoint1, iTimePoint2 : int64;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  if QueryPerformanceFrequency(iFrequency) = 0 then
    raise Exception.Create('The installed hardware does not support a high-resolution performance counter!');
end;

procedure TForm1.StartTiming;
begin
  QueryPerformanceCounter(iTimePoint1);
end;

// das Ergebnis ist in Sekunden
function TForm1.SecondsSinceStartTiming: double;
begin
  QueryPerformanceCounter(iTimePoint2);
  result := (iTimePoint2 - iTimePoint1) / iFrequency;
end;

procedure TForm1.DoRender;
var aFPSTime : double;
begin
  // Das eigenliche Rendern ausführen
  DoExecRender;
  // Anzahl der Frames erhöhen
  inc(FFrameCount);
  aFPSTime := SecondsSinceStartTiming;
  // die FPS-Berechnung nur 1x pro Sekunde ausführen
  if aFPSTime >= 1.0 then
  begin
    aFramesPerSecond := round(FFrameCount / aFPSTime);
    StartTiming;
  end;
end;
Das Problem ist halt, dass die Performance-Counter für jeden Core unterschiedlich seien können. Um das Problem zu beheben muss man den Thread/Prozess, in dem QueryPerformanceXXXXX aufgerufen wird an eine CPU binden.
Von AMD gibt es ein Tool, mit dem die AMD-Prozessor-Counter synchronisiert werden und es somit zu keinen Fehlern mehr kommen kann, weiß aber gerade nicht, wie das heißt. Ich glaube sogar, dass die neueren CPUs die Counter automatisch synchronisieren, ist aber nur Spekulation. Ich hatte z.B. bei meinem AMD X2 4800+ noch nie Probleme mit QueryPerformanceCounter - auch ohne installiertes AMD-Tool.

EWeiss 17. Jun 2008 16:18

Re: Exakte FPS
 
@littleDave

Danke für das Beispiel ;)

Da ihr nicht näher auf meine code eingegangen seid gehe ich davon aus das er
die für GetTickCount richtigen werte wieder spiegelt.

Mein Problem war halt die aussage das unter Vista fast nichts mehr gehen soll was ich eigentlich nicht so recht glauben mag..
Auch wenn Vista , so wie gehört OpenGl nur Softwaremäßig unterstützt und nicht die Grafikkarte dazu verwendet

Leider kann ich die aussage nicht nachvollziehen da ich kein Vista habe.
Programmieren für ein system das man nicht hat ist das gleiche wie ein Schuss ins Dunkle.

Habe versucht mit diesen Funktionen es unter Vista schneller zu machen.
1. Entfernen von Fulldrag
2. Display größe ändern entfernt macht probleme bei Systemen mit 2 Monitoren.
3. Diese Funktion addiert..

Delphi-Quellcode:
procedure zUpdateWindow (Handle : integer; FlagMode : LongBool);
begin
    InvalidateRect(Handle, nil, FlagMode);
    UpdateWindow(Handle);

end;
anstelle von
Delphi-Quellcode:
wglSwapBuffers(glDc)
Konnte es aber nicht testen

gruss Emil

Namenloser 17. Jun 2008 16:25

Re: Exakte FPS
 
Also wenn die Framerate imemr gleich ist würde ich vermuten, dass du
a) eine andere Bremse hast
b) VSync aktiviert

Du kannst dein Projekt ja mal anhängen, damit User, die Vista haben (zum Beispiel ich), es für dich testen können.

EWeiss 17. Jun 2008 16:29

Re: Exakte FPS
 
Zitat:

Zitat von NamenLozer
Also wenn die Framerate imemr gleich ist würde ich vermuten, dass du
a) eine andere Bremse hast
b) VSync aktiviert

Du kannst dein Projekt ja mal anhängen, damit User, die Vista haben (zum Beispiel ich), es für dich testen können.

Jo dann hier ist es mal ;)
Habs schon mal hochgeladen (wieder gelöscht) aber egal ..

Zitat:

VSync aktiviert
???? weiss nicht was du meinst (die einstellung der Grafikkarte ?)
wenn ja das macht NVidea automatisch aktivieren/deaktivieren

Immer gleich ist sie nicht OpenGL verbraucht halt sehr wenig CPU von daher mag das schon stimmen
Sie ändert sich ja auch wenn ich das Window ziehe.

EDIT:
Scheint keiner testen zu wollen
habs wieder gelöscht da sonst zu viele verschiedene Versionen von BassVis existieren.

gruss Emil

littleDave 17. Jun 2008 16:40

Re: Exakte FPS
 
Zitat:

Zitat von EWeiss
Zitat:

VSync aktiviert
???? weiss nicht was du meinst

Da hab ich mal versucht zu erklären, was vSync ist

EWeiss 17. Jun 2008 16:53

Re: Exakte FPS
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von littleDave
Zitat:

Zitat von EWeiss
Zitat:

VSync aktiviert
???? weiss nicht was du meinst

Da hab ich mal versucht zu erklären, was vSync ist

Habs gelesen gute erklärung.
Lag also mit meiner vermutung richtig das es um die einstellung der Hardware geht.

Werd das mal aktivieren ;)
Kann nicht schaden steht bei mir zwar automatisch nur wann es aktiviert wird steht nicht dabei ;)

EDIT:
gebracht hat es aber nichts.
Immer noch 40 FPS

gruss Emil

Muetze1 17. Jun 2008 17:31

Re: Exakte FPS
 
Zitat:

Zitat von littleDave
Die Genauigkeit von GetTickCount hat maximal 1ms, ...

Afaik hängt GetTickCount() noch immer am guten alten HW Timer 1 und der sollte somit eine Auflösung von 18,2 ms haben...

littleDave 17. Jun 2008 17:34

Re: Exakte FPS
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von littleDave
Die Genauigkeit von GetTickCount hat maximal 1ms, ...

Afaik hängt GetTickCount() noch immer am guten alten HW Timer 1 und der sollte somit eine Auflösung von 18,2 ms haben...

Wieder was gelernt. Ich wusste es selbst nicht genau, also hab ich einfach 1ms gesagt, da das Ergebnis ja eine cardinal-Variable ist ;-) Aber gut zu wissen. Also ich kann nur sagen, dass meins eine Vermutung war, von daher hast du, Muetze1, recht glaub ich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:26 Uhr.
Seite 1 von 2  1 2      

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