Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow disabling low-processor mode on headless platforms #47138

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Mar 18, 2021

This can be used when you want processing to happen as fast as possible (at the cost of high CPU usage). This is generally not what you want for a dedicated game server, so low processor-mode is still enabled by default on headless platforms.

  • Enable low-processor mode by default on headless platforms (mimics the previous behavior).
  • Use a 60 FPS limit on headless mode by default (down from 144 FPS). This can be overridden by changing the Server override for application/run/low_processor_mode_sleep_usec. This allows effectively changing the server's _process() tick rate, balancing CPU usage and network bandwidth usage with latency.

This closes #32404.

Question: Can someone check if feature tags are actually case-sensitive? The documentation claims they are, but I noticed the Windows pen driver code uses .windows instead of .Windows to override the default setting. cc @bruvzg

@Calinou Calinou requested review from a team as code owners March 18, 2021 18:12
@Calinou Calinou added enhancement topic:core topic:porting cherrypick:3.x Considered for cherry-picking into a future 3.x release labels Mar 18, 2021
@Calinou Calinou added this to the 4.0 milestone Mar 18, 2021
@akien-mga
Copy link
Member

You have some changes that I already checked in in master, needs a rebase.

This can be used when you want processing to happen as fast as possible
(at the cost of high CPU usage). This is generally not what you want for
a dedicated game server, so low processor-mode is still enabled by default
on headless platforms.

- Enable low-processor mode by default on headless platforms
  (mimics the previous behavior).
- Use a 60 FPS limit on headless mode by default (down from 144 FPS).
  This can be overridden by changing the Server override for
  `application/run/low_processor_mode_sleep_usec`.
  This allows effectively changing the server's `_process()` tick rate,
  balancing CPU usage and network bandwidth usage with latency.
@Calinou Calinou force-pushed the server-low-processor-mode branch from b130088 to ab3df16 Compare March 18, 2021 19:35
@Calinou
Copy link
Member Author

Calinou commented Mar 18, 2021

You have some changes that I already checked in in master, needs a rebase.

Fixed.

Also, in the master branch, this pull request won't have any effect since the server platform hasn't been reimplemented yet. When we get around to making the headless DisplayServer, it should have the Server feature tag applied to it (or server if we settle on making all feature tags lowercase). Unless we decide to rename it to headless, that is 🙂

@@ -2555,7 +2561,7 @@ bool Main::iteration() {
return exit;
}

OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
OS::get_singleton()->add_frame_delay();
Copy link
Collaborator

Choose a reason for hiding this comment

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

window_can_draw depends on the OS/DisplayServer, e.g. window is minimized.
So, frame delay won't be applied when window is minimized, resulting, I think, in much higher CPU usage.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I thought it returned a constant based on the platform.

Do you know if there's a way to make this configurable for the server platform without impacting the behavior on minimized windows?

Copy link
Collaborator

@Faless Faless Mar 19, 2021

Choose a reason for hiding this comment

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

well, more then one, I'm just not sure what's the best approach.

  • OS implementations could change is_in_low_processor_usage_mode when minimized instead, but that might have side effects on some platforms
  • Otherwise get_low_processor_usage_mode_sleep_usec could be adjusted when the display is headless.

In general, I don't like the fact that low_process_mode_sleep_usec is abused this way, but it's hard to reconcile the need of different platforms (different window/app lifecycle), display servers (vsync/headless), and the extra constrain of "adding more delay"

@Faless Faless requested a review from a team March 19, 2021 00:17
@bruvzg
Copy link
Member

bruvzg commented Mar 22, 2021

Question: Can someone check if feature tags are actually case-sensitive? The documentation claims they are, but I noticed the Windows pen driver code uses .windows instead of .Windows to override the default setting. cc @bruvzg

godot/core/os/os.cpp

Lines 364 to 370 in 07f076f

bool OS::has_feature(const String &p_feature) {
if (p_feature == get_name()) {
return true;
}
#ifdef DEBUG_ENABLED
if (p_feature == "debug") {
return true;

It seems to be case-sensitive, the pen driver override should be changed to .Windows.

@Calinou
Copy link
Member Author

Calinou commented Mar 22, 2021

@bruvzg Thanks! I opened a pull request to fix this: #47255

@Faless
Copy link
Collaborator

Faless commented Mar 22, 2021

I've been wondering, would it make sense to have the !p_can_draw sleep time independent from the low_processor_mode one?

Normally, the engine is expected to run at a fixed iteration per second. This is usually handled by vsync. But as I understand it, when the window is minimized vsync won't happen, and we would end up doing millions of iterations per second. To avoid this we add the low_processor_usage_mode_sleep_usec delay (even if we are not in low_processor_mode).

But what we really want to do in that case, is trying to keep the FPS constant, so if we are not in low_processor_usage_mode what we should do is keep the FPS value consistent with the previous one, i.e. the vsync-ed one.

When vsync is unknown (headless) or disabled, either target_fps must be specified, or a default can be used (e.g. 60).

I'm also unsure if we should keep low_processor_usage_mode_sleep_usec at all. It's confusing, and if you are creating an app, you can set the target_fps if you really want the loop to sleep more and have almost the same result (keeping low_processor_usage_mode = true).

Thoughts? ( @reduz )

@Calinou
Copy link
Member Author

Calinou commented Mar 22, 2021

@Faless See also godotengine/godot-proposals#2001, where I suggested capping the FPS to 20 in unfocused and minimized windows by default (adjustable with project settings).

@Faless
Copy link
Collaborator

Faless commented Mar 22, 2021

See also godotengine/godot-proposals#2001, where I suggested capping the FPS to 20 in unfocused and minimized windows by default (adjustable with project settings).

Actually, on e.g. Windows FPS are indeed capped to 144 FPS like the server platform in the original issue. Exactly as a side effect of low_processor_mode_sleep_usec being applied when !p_can_draw.

@Faless
Copy link
Collaborator

Faless commented Mar 22, 2021

So, maybe with hindsight from your proposal, we could change low_processor_mode_sleep_usec to be low_processor_mode_max_fps and have a low_processor_mode_when_incative (unfocused/minimized) boolean option,

@Calinou
Copy link
Member Author

Calinou commented Mar 22, 2021

@Faless Sounds good to me 🙂

However, I want to stress that even with low-processor mode enabled, the default FPS limit is quite high. Being able to use a lower FPS limit selectively can help a lot with decreasing power consumption. This is why I suggested having separate project settings for each state (focused, unfocused, minimized).

Right now (without relying on scripts), you can decrease the low processor mode FPS limit globally, but then it becomes too low when you're actually using the application.

@PanTrakX
Copy link

This can be used when you want processing to happen as fast as possible (at the cost of high CPU usage). This is generally not what you want for a dedicated game server, so low processor-mode is still enabled by default on headless platforms.

Why this is not something you generally want?
What type of games with a dedicated game server is better suited with low-process enabled and what with it disabled?
If it is a session based competitive 5v5 fps game it is better with low-process disabled right?

@Calinou
Copy link
Member Author

Calinou commented Sep 22, 2021

Why this is not something you generally want?

Simulating _process() as fast as possible wastes CPU cycles. Not only this increases power usage and heat/noise emissions, this is problematic for server environments where you're hosting multiple game servers on the same machine. To prevent CPU resource leeching, most VPS hosts will also shut down your machine if its load average becomes too high over a long period of time.

If it is a session based competitive 5v5 fps game it is better with low-process disabled right?

No, you should still keep low-processor mode enabled in this case, as movement updates should happen in _physics_process() instead of _process(). You don't want network updates to be sent at a variable rate depending on how fast the server simulates things 🙂

@YuriSizov YuriSizov modified the milestones: 4.0, 4.1 Feb 9, 2023
@YuriSizov YuriSizov modified the milestones: 4.1, 4.2 Jun 14, 2023
@AThousandShips AThousandShips modified the milestones: 4.2, 4.3 Oct 26, 2023
@akien-mga akien-mga removed this from the 4.3 milestone Jun 28, 2024
@akien-mga akien-mga added this to the 4.x milestone Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cherrypick:3.x Considered for cherry-picking into a future 3.x release enhancement topic:core topic:porting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Server binary max fps steady at 144
7 participants