Skip to content

Add an Engine method to get the 1% percentile low FPS#67136

Open
Calinou wants to merge 1 commit into
godotengine:masterfrom
Calinou:engine-add-fps-1-percent-low
Open

Add an Engine method to get the 1% percentile low FPS#67136
Calinou wants to merge 1 commit into
godotengine:masterfrom
Calinou:engine-add-fps-1-percent-low

Conversation

@Calinou

@Calinou Calinou commented Oct 9, 2022

Copy link
Copy Markdown
Member

Measuring performance by only looking at the average FPS can be misleading, as microstutters will not be represented in the final value. This can lead to confusion as a game might have an average FPS of over 60, yet it can feel very stuttery if its 1% low FPS are in the single digits.

This adds a Engine method and profiler readout for the 1% low FPS over the last 100 rendered frames. This is a moving metric by definition, but it still helps make these FPS drops more noticeable compared to an average readout.

This closes godotengine/godot-proposals#5459.

Testing project: test_fps_1_percent_low.zip

Preview

Performance monitor

2022-10-09_02 13 51

Video

FPS cap is engaged at the middle of the video. The recording has some stuttering, but it feels smooth in practice. The [Core] line is the metric introduced in this PR, while [Script] is a GDScript prototype I left in the testing project for comparison.

out.mp4

@Calinou Calinou requested review from a team as code owners October 9, 2022 14:29
@Calinou Calinou added this to the 4.0 milestone Oct 9, 2022
Comment thread main/main.cpp Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • There's an interesting comment on line 3173 about FPS reporting. Based on that, shouldn't this code be inside the IF from line 3173 (the if below)?
  • Suggestion: Since it is already printing the FPS below (L3178 and 3181), WDYT aboud add the 1% low FPT there too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an interesting comment on line 3173 about FPS reporting. Based on that, shouldn't this code be inside the IF from line 3173 (the if below)?

1% low FPS reporting is designed to be updated as often as possible, rather than just once per second. This makes the value less stable when you print out its value in _process, but it makes changes more reactive, which I think is better overall.

The editor performance monitor and --print-fps will still only update the displayed value once per second due to how they work (see the graph screenshot in OP).

In the long term, we could look into adding a smoothing algorithm like #63356, but I think this is better left for a future PR.

Suggestion: Since it is already printing the FPS below (L3178 and 3181), WDYT aboud add the 1% low FPT there too?

That's a good idea. I implemented this 🙂

Comment thread main/main.cpp Outdated
@Calinou Calinou force-pushed the engine-add-fps-1-percent-low branch 2 times, most recently from 957c0fb to c3edd33 Compare October 12, 2022 18:21
@connorshea

Copy link
Copy Markdown

Generally, when discussing performance (at least for web apps and APIs), the common thing to call this would be "99th percentile" (for the longest/slowest 1% of requests).

e.g. Sentry's performance tools, Google Cloud's latency metrics, Datadog's "percentile aggregations", etc.

To mirror that, should this be called "1st percentile FPS"? (or even just call it 99th percentile FPS, since that's still true here, it's just that in this case we want higher numbers rather than wanting lower numbers).

@Calinou

Calinou commented Oct 22, 2022

Copy link
Copy Markdown
Member Author

Generally, when discussing performance (at least for web apps and APIs), the common thing to call this would be "99th percentile" (for the longest/slowest 1% of requests).

See https://www.capframex.com/blog/post/Explanation%20of%20different%20performance%20metrics and https://www.capframex.com/blog/post/The%20challenge%20of%20displaying%20performance%20metrics%20as%20FPS. The "1% low" term generally seems more popular than "99th percentile" nowadays in gaming, though both are open to ambiguity as shown in the linked articles.

@akien-mga

Copy link
Copy Markdown
Member

We discussed this in a PR review meeting.

The feature looks nice and useful, but we have some concerns on the implementation:

  • Is this the one metric that will need? Or will there be more similar metrics that we'll want to add, each time requiring a new Engine property and adding more computation to Main::iteration?
  • Computing this in Main::iteration seems a bit wasteful performance-wise, especially if it's intended for debugging and not something that users actually need in production constantly (unlike computations done for the idle and physics frame). Maybe this can be handled in Performance itself in a way that would not affect production builds? Or in the editor profilers?

@Calinou

Calinou commented Nov 15, 2022

Copy link
Copy Markdown
Member Author
  • Is this the one metric that will need? Or will there be more similar metrics that we'll want to add, each time requiring a new Engine property and adding more computation to Main::iteration?

As I wrote in OP, there are other "% low" metrics out there, but 1% low is by far the most commonly used one.

  • Computing this in Main::iteration seems a bit wasteful performance-wise, especially if it's intended for debugging and not something that users actually need in production constantly (unlike computations done for the idle and physics frame). Maybe this can be handled in Performance itself in a way that would not affect production builds? Or in the editor profilers?

The computation could be disabled in release builds, but it only takes a few microseconds per frame so I'd prefer not. It should be possible for developers to profile fully optimized release exports after all.

@Calinou Calinou force-pushed the engine-add-fps-1-percent-low branch from c3edd33 to 4abe42e Compare January 29, 2023 23:03
@akien-mga akien-mga modified the milestones: 4.0, 4.x Jan 30, 2023
@Calinou Calinou force-pushed the engine-add-fps-1-percent-low branch from 4abe42e to e851733 Compare July 23, 2024 15:41
@Calinou

Calinou commented Jul 23, 2024

Copy link
Copy Markdown
Member Author

Rebased and tested again, I'm noticing strange behavior from the 1% low FPS counter (look at the Core line):

fps_low.mp4

Most noticeably, when capping at 30 FPS, it never goes past 10 FPS (which is a FPS cap that is momentarily applied when I go to the 30 FPS cap, but it stays here even if I stay at a perfect 30 FPS for 10+ seconds).

Edit: Fixed thanks to @CaelusV's review comment below.

Comment thread main/main.cpp Outdated
@Calinou Calinou force-pushed the engine-add-fps-1-percent-low branch from e851733 to b2ce236 Compare July 24, 2024 15:52
@AThousandShips AThousandShips changed the title Add a Engine method to get the 1% percentile low FPS Add an Engine method to get the 1% percentile low FPS Jul 24, 2024
Comment thread doc/classes/Performance.xml Outdated
Measuring performance by only looking at the average FPS can be misleading,
as microstutters will not be represented in the final value.
This can lead to confusion as a game might have an average FPS of over 60,
yet it can feel very stuttery if its 1% low FPS are in the single digits.

This adds a Engine method and profiler readout for the 1% low FPS over
the last 100 rendered frames. This is a moving metric by definition,
but it still helps make these FPS drops more noticeable compared to an
average readout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an Engine method and Performance monitor to return the 1% low FPS ("99th percentile")

6 participants