Gorgon
Show / Hide Table of Contents

Class GorgonTiming

Timing data for code within a Gorgon Idle loop.

Inheritance
object
GorgonTiming
Inherited Members
object.ToString()
object.Equals(object)
object.Equals(object, object)
object.ReferenceEquals(object, object)
object.GetHashCode()
object.GetType()
object.MemberwiseClone()
Namespace: Gorgon.Timing
Assembly: Gorgon.Core.dll
Syntax
public static class GorgonTiming
Remarks

This class is used to calculate the time it takes for a single iteration an idle loop to execute. It will gather statistics such as the frames per second, the time elapsed since the application started and peaks, lows and averages for those values.

To use this in a custom idle processing loop the user should initialize using the StartTiming<T>() method, and then, in the loop, call the Update() method to populate the data with the most recent timings.

Examples

When using the Gorgon.UI.GorgonApplication class, the timing code is automatically updated by its own idle loop:

public static bool MyLoop()
{
    Console.CursorLeft = 0;
    Console.CursorTop = 0;
	Console.WriteLine($"FPS: {GorgonTiming.FPS}");

	return true;
}

public static Main()
{
	GorgonApplication.Run(MyLoop);
}

And here is a a custom application loop using the GorgonTiming class:

// This assumes the Win32 API call to PeekMessage is imported.
public void DoLoop()
{
	MSG message;  // Win32 Message structure.

	// Before loop execution.
    GorgonTiming.StartTiming<GorgonTimerQpc>();

	while (!API.PeekMessage(out message, IntPtr.Zero, 0, 0, PeekMessage.NoRemove))
    {
		GorgonTiming.Update();

		// Do your processing.
	}
}

Properties

| Edit this page View Source

AverageDelta

Property to return the average number of seconds to run the idle loop for a single iteration.

Declaration
public static float AverageDelta { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

This value is affected by the TimeScale property.

| Edit this page View Source

AverageFPS

Property to return the average FPS.

Declaration
public static float AverageFPS { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

| Edit this page View Source

AverageUnscaledDelta

Property to return the average number of seconds to run the idle loop for a single iteration.

Declaration
public static float AverageUnscaledDelta { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

This value is not affected by the TimeScale property because it is meant to be used in performance measurement.

| Edit this page View Source

Delta

Property to return the number of seconds to run the idle loop for a single iteration with scaling.

Declaration
public static float Delta { get; }
Property Value
Type Description
float
Remarks

This value is affected by the TimeScale property.

| Edit this page View Source

FPS

Property to return the number of frames per second.

Declaration
public static float FPS { get; }
Property Value
Type Description
float
Remarks

This is a value to indicate how many frames of information can be sent to the display by a video device within 1 second. While it is useful as a metric, it is not a good measure of performance because FPS values are non-linear. This means that a rate of 1000 FPS dropping to 500 FPS is not a sign of poor performance. Simply because the video device may not have had any work to do prior to measurement, and on the second reading, it drew an object to the display.

The proper value to use for performance is the Delta value. This tells how many seconds have occurred between the last time a frame was drawn the beginning of the next frame.

See the article at https://cgvr.cs.ut.ee/wp/index.php/frame-rate-vs-frame-time/ for more information on using frame delta instead of frames per second.

| Edit this page View Source

FrameCount

Property to return the number of frames that have been presented.

Declaration
public static uint FrameCount { get; }
Property Value
Type Description
uint
| Edit this page View Source

FrameCountULong

Property to return the number of frames that have been presented (using an unsigned 64 bit value).

Declaration
public static ulong FrameCountULong { get; }
Property Value
Type Description
ulong
| Edit this page View Source

HighestDelta

Property to return the highest idle loop delta.

Declaration
public static float HighestDelta { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

This value is not affected by the TimeScale property because it is meant to be used in performance measurement.

| Edit this page View Source

HighestFPS

Property to return the highest FPS.

Declaration
public static float HighestFPS { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

| Edit this page View Source

LowestDelta

Property to return the lowest idle loop delta.

Declaration
public static float LowestDelta { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

This value is not affected by the TimeScale property because it is meant to be used in performance measurement.

| Edit this page View Source

LowestFPS

Property to return the lowest FPS.

Declaration
public static float LowestFPS { get; }
Property Value
Type Description
float
Remarks

Note that the averaged/min/max calculations are affected by the length of time it takes to execute a single iteration of the idle loop and will not have meaningful data until the application loop begins processing after a call to one of the GorgonApplication.Run methods.

| Edit this page View Source

MaxAverageCount

Property to set or return the maximum number of iterations before an average value is reset.

Declaration
public static long MaxAverageCount { get; set; }
Property Value
Type Description
long
Remarks

This only applies to the AverageFPS, AverageDelta and AverageUnscaledDelta properties.

Note that the higher the value assigned to this property, the longer it'll take for the averages to compute, this is in addition to any overhead from the time it takes to execute a single iteration of the idle loop.

| Edit this page View Source

MaximumFrameDelta

Property to set or return the maximum frame delta, in seconds.

Declaration
public static double MaximumFrameDelta { get; set; }
Property Value
Type Description
double
Remarks

This value is used to cap the Delta and UnscaledDelta values so that frames can appear more smoothly in case of a long delay between frames. By default, this is set to 0.33333 seconds.

| Edit this page View Source

MillisecondsSinceStart

Property to return the number of milliseconds since a Gorgon application was started.

Declaration
public static float MillisecondsSinceStart { get; }
Property Value
Type Description
float
Remarks

This property starts counting at the first call to one of the GorgonApplication.Run methods. If this property is called prior to that, then it will return 0.

This value is affected by the TimeScale property, and will not update if the application is not in the foreground unless the application allows for background processing.

| Edit this page View Source

SecondsSinceStart

Property to return the number of seconds since a Gorgon application was started.

Declaration
public static float SecondsSinceStart { get; }
Property Value
Type Description
float
Remarks

This property starts counting at the first call to one of the GorgonApplication.Run methods. If this property is called prior to that, then it will return 0.

This value is affected by the TimeScale property, and will not update if the application is not in the foreground unless the application allows for background processing.

| Edit this page View Source

TimeScale

Property to scale the frame delta times.

Declaration
public static float TimeScale { get; set; }
Property Value
Type Description
float
Remarks

Setting this value to 0 will pause, and a negative value will move things in reverse when using Delta.

| Edit this page View Source

TimingStarted

Property to return whether or not the timing has been started by StartTiming<T>().

Declaration
public static bool TimingStarted { get; }
Property Value
Type Description
bool
| Edit this page View Source

UnscaledDelta

Property to return the number of seconds to run the idle loop for a single iteration.

Declaration
public static float UnscaledDelta { get; }
Property Value
Type Description
float
Remarks

This is a value to indicate how long it took an iteration of the idle loop to execute. Including the time it took for a video device to draw data. This is the preferred value to read when checking for performance.

The article at https://cgvr.cs.ut.ee/wp/index.php/frame-rate-vs-frame-time/ has more information on using frame delta instead of frames per second.

This is the same as the Delta property when the TimeScale is set to 1.0f, otherwise, this value is not affected by TimeScale.

Because it is unaffected by TimeScale, this value is the one that should be used when measuring performance.

Methods

| Edit this page View Source

FpsToMicroseconds(double)

Function to convert the desired frames per second to microseconds.

Declaration
public static double FpsToMicroseconds(double fps)
Parameters
Type Name Description
double fps

Desired frames per second.

Returns
Type Description
double

Frames per second in microseconds.

| Edit this page View Source

FpsToMilliseconds(double)

Function to convert the desired frames per second to milliseconds.

Declaration
public static double FpsToMilliseconds(double fps)
Parameters
Type Name Description
double fps

Desired frames per second.

Returns
Type Description
double

Frames per second in milliseconds.

| Edit this page View Source

Reset()

Function to clear the timing data and reset any timers.

Declaration
public static void Reset()
Remarks

Like Update(), you do not need to call this method unless you have your own mechanism for handling an idle time loop.

Values set by the user (e.g. MaxAverageCount, etc...) will not be reset.

| Edit this page View Source

StartTiming<T>()

Function to initialize the timing data.

Declaration
public static void StartTiming<T>() where T : class, IGorgonTimer, new()
Type Parameters
Name Description
T

The type of timer to use. Must be a class, implement IGorgonTimer and have a parameterless constructor.

Remarks

Applications must call this method prior to using this class. Otherwise, no data will be present.

tip

If you are using the Gorgon.Windows.GorgonApplication class, you do not need to call this method since it contains its own idle processing and therefore will call this method on your behalf.

| Edit this page View Source

Update()

Function to gather timing data.

Declaration
public static void Update()
Remarks

Ensure that the StartTiming<T>() was called prior to calling this method, or no meaningful data will be collected.

tip

If you are using the Gorgon.Windows.GorgonApplication class, you do not need to call this method since it contains its own idle processing and therefore will call this method on your behalf.

  • Edit this page
  • View Source
In this article
Back to top Copyright 2023 - Licensed under the MIT license by Michael Winsor (Tape_Worm).
Send comments on this topic to the author