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

maplibre-demo: High CPU and GPU usage on macOS while idle #187

Open
vollkorntomate opened this issue Oct 25, 2022 · 10 comments
Open

maplibre-demo: High CPU and GPU usage on macOS while idle #187

vollkorntomate opened this issue Oct 25, 2022 · 10 comments
Labels
bug Something isn't working

Comments

@vollkorntomate
Copy link

vollkorntomate commented Oct 25, 2022

The maplibre-demo binary has a quite high CPU and GPU usage when doing nothing. Activity monitor shows around 40% CPU usage and between 25-35% GPU usage while the app is in the foreground (and has focus) and no layers are being visibly rendered and the map is not interacted with. Roughly the same usage is reported while the app is in the background (window has no focus)

🤔 Expected Behavior

The CPU and GPU usage should be at a minimum, near 0%.

😯 Current Behavior

See above.

The latest commits (from Oct 23 and 24) seem to have improved the issue. Earlier, GPU usage was near 100% while in background. However, this improvement might also be due to the macOS Ventura update.

💁 Possible Solution

I was able to narrow down the source of the problem to apparently be inside maplibre-winit/src/winit/mod.rs:170 and the call to map_schedule::InteractiveMapSchedule::update_and_redraw(), since the RedrawRequested event fires multiple times per second and thus the map re-renders all the time, costing CPU and GPU resources.

A possible solution might be to only redraw the map if

  1. it has been moved or zoomed since the last redraw or
  2. loading the map hasn't finished and thus new objects need to be rendered

🌍 Your Environment

  • Desktop
    • macOS 13.0 (Ventura)
    • M1 Max, 24 GPU Cores
  • commit ec1ad07
  • built with cargo build -p maplibre-demo
  • run with ./target/debug/maplibre-demo headed
@vollkorntomate vollkorntomate added the bug Something isn't working label Oct 25, 2022
@maxammann
Copy link
Collaborator

Did you run your experiments in release mode?

I'm actually not entirely certain what to expect in terms of numbers. I think there are also multiple effects which play a role here:

  • maplibre-rs is in background and currently not visible

    In this case its the job of the OS to reduce the framerate. Browsers like Firefox do this sucessfully right now with maplibre-rs
    No animations are currently running in maplibre-rs. The map is not moved. Data is not updated. Window is not resized. -> We should limit the frame-rate to 0 FPS in this case. No need to redraw. We need an issue for that.

After all I think that maplibre-rs even when running with 60FPS it should not consume more than 5% of CPU if the map is not moved. We need to get a feeling first on how much "energy" a simple renderer should take (energy = CPU cycles/s and GPU usage).

So we need more numbers here before.

@vollkorntomate
Copy link
Author

vollkorntomate commented Oct 26, 2022

Did you run your experiments in release mode?

I actually ran them in debug mode. Just now I tried it again in release mode and it doesn't seem to make any difference, the numbers are the same.

No animations are currently running in maplibre-rs. The map is not moved. Data is not updated. Window is not resized. We should limit the frame-rate to 0 FPS in this case. No need to redraw. We need an issue for that.

Is this linked to an issue or somewhere from the roadmap?

@maxammann
Copy link
Collaborator

Is this linked to an issue or somewhere from the roadmap?

Not yet, but we probably could create an RFC which is called "energy saving", or just directly create an issue.

@maxammann maxammann added this to the Far far future milestone Jul 26, 2024
@HKalbasi
Copy link

HKalbasi commented Oct 7, 2024

I'm also experiencing the 100% core usage problem. I think the problem here is that the handler of WindowEvent::RedrawRequested calls map.window().request_redraw() again, effectively creating a busy wait loop, so the core usage is always 100% regardless of the performance of rendering.

@maxammann
Copy link
Collaborator

I'm also experiencing the 100% core usage problem. I think the problem here is that the handler of WindowEvent::RedrawRequested calls map.window().request_redraw() again, effectively creating a busy wait loop, so the core usage is always 100% regardless of the performance of rendering.

The winit library is sadly a bit inconsistent sometimes. I believe that call is required. The library is also only rendering 60FPS. So the redraw function is called only that often.

In not sure if the 100% are to be expected or not.

If the CPU is fast then it should idle and CPU utilization should be below 100%. Maybe this is a bug in wgpu?

@HKalbasi
Copy link

HKalbasi commented Oct 9, 2024

The library is also only rendering 60FPS. So the redraw function is called only that often.

I commented out the rendering (the run_schedule line in the same loop) and I'm still getting the 100% cpu usage. Either I removed that logic, or it is not working. Where is the code that limit it to 60fps? Maybe it is not working on my machine (for the record, I'm running it on a vm, it might be the problem)

I believe that call is required.

Why? I removed the request redraw call from there and added it to the device input event, and I got the same result with near zero cpu usage.

@maxammann
Copy link
Collaborator

Why? I removed the request redraw call from there and added it to the device input event, and I got the same result with near zero cpu usage.

Did it still execute the rendering loop 60 frames a second? I remember that this is platform depending so it might be only required on iOS.

@maxammann
Copy link
Collaborator

I commented out the rendering (the run_schedule line in the same loop) and I'm still getting the 100% cpu usage.

That could be by design. I believe the OS is responsible for calling the loop function. How often it is doing that depends on the OS. The OS can decide for instance to suspend rendering.

I'm not sure if what you experience is b design though. I imagine without the run_schedule it is just an empty while loop that gets executed.

@maxammann
Copy link
Collaborator

@HKalbasi On which OS are you? I'm testing on wayland right now and I have only 5% CPU usage.

@HKalbasi
Copy link

I'm on ubuntu 22.04 on wayland on a vm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants