gamepads icon indicating copy to clipboard operation
gamepads copied to clipboard

High CPU usage

Open natebot13 opened this issue 10 months ago • 5 comments

I think this busy loop is causing a rather high CPU utilization on windows. I hear this package might be swapping over to the newer windows gaming input API, but wanted to make an issue so this could hopefully be somewhat tracked.

https://github.com/flame-engine/gamepads/blob/main/packages/gamepads_windows/windows/gamepad.cpp#L83

natebot13 avatar Feb 13 '25 04:02 natebot13

Hight CPU usage in windows here too, from 6% without connecting any gamepad to 20% when i turn on my gamepad.

miguelsotobaez avatar Sep 08 '25 01:09 miguelsotobaez

I hear this package might be swapping over to the newer windows gaming input API

If anyone wants to submit a PR for improving the existing integration feel free to do so, because I have a feeling there will be some time until someone has time to move to another windows API.

spydon avatar Sep 08 '25 15:09 spydon

It looks like in gamepad.cpp there is a wihle loop that polls joyGetPosEx in windows API without any rate limiting.

I don't know if windows API supports subscribing to a stream or if the gamepads lib has to decide on a polling rate.

lea108 avatar Oct 08 '25 19:10 lea108

This fix my issue, just put a sleep 8, this resolve my CPU from 20% to < 3%

I cannot create a pull request now, but hope someone can check if its a good solution or not. At least for me it's working fine.

while (gamepad->alive) {
    JOYINFOEX previous_state = state;
    MMRESULT result = joyGetPosEx(joy_id, &state);
    if (result == JOYERR_NOERROR) {
      if (are_states_different(previous_state, state)) {
        std::list<Event> events = diff_states(gamepad, previous_state, state);
        for (auto joy_event : events) {
          if (event_emitter.has_value()) {
            (*event_emitter)(gamepad, joy_event);
          }
        }
      }
    } else {
      std::cout << "Fail to listen to gamepad " << joy_id << std::endl;
      gamepad->alive = false;
      gamepads.erase(joy_id);
    }
    
    // Rate limiting: Sleep for 8ms (~125 Hz polling rate)
    // This prevents high CPU usage from the busy loop
    // Most gamepads operate at 60-120 Hz, so 125 Hz is more than enough
    // to capture all input events without missing any
    Sleep(8);
  }

miguelsotobaez avatar Nov 08 '25 19:11 miguelsotobaez

@miguelsotobaez Your solution looks resonable. However, it likely increases the risk of https://github.com/flame-engine/gamepads/issues/79 occurring, which is the main reason why I haven't submitted your solution as a PR.

That said. It might still be a better trade off to actually do the fix that you propose as it will impact anyone using gamepads on Windows. While the linked issue mainly impact users if you disconnect a gamepad while the game runs which most likely mainly affect developers while they develop their game and jump between play-testing and coding on their keyboard and have a battery powered controller that disconnects due to inactivity.

Edit: long term I think both issues needs fixing, but in the mean time fixing the high CPU usage with the sleep might still be a good move to do.

lea108 avatar Nov 09 '25 14:11 lea108