-
Notifications
You must be signed in to change notification settings - Fork 109
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
High CPU usage on Mac #228
Comments
I've used this code from BTerm examples:
but thing is, I don't want to consume the event. I want to let Can we please have Thank you! |
Which is probably even more important – I don't see a way to put the process to sleep while waiting for the input event in |
Hey @singalen, while we wait for @thebracket to take a look at this, I tried fix which, while not polished, isn't that awful. https://github.com/BiosElement/bracket-lib/commit/e8cd34112ade911bd6d1d460a209301b8e660e67 Basically just using winit's waituntil instead of polling, which means the sleep which adds input latency is removed. CPU usage and input latency both seem reasonable now. |
The approach in BiosElement's file is really good. I didn't know |
On Windows, I'm getting some odd results - |
…. Then change control flow to WaitUntil, pausing until the next frame - OR waking up when a new event arrives. #228
There's a potential fix in the branch https://github.com/amethyst/bracket-lib/tree/issue-228-high-cpu
I could use some testing on this, if you don't mind. |
I'll be looking at this later today, but in response to the 'zooming' @thebracket , this is by design I believe. WaitUntil 'sleeps' until a certain time OR until an event triggers. So this could be considered 'good' in terms of responsiveness since I'd want the game to be responsive, but within that event trigger there should probably be tickrate limiting. I did notice it capped at my Desktop's vsync, so this isn't the worst behavior, however things like animations would suffer from this rapidly changing fps. |
That's why I went with capping the render/update FPS and WaitUntil - it should still respond to messages rapidly, but without suddenly accelerating your game. It seems to work ok on a few tests I ran, but I imagine it'll need some tweaking. |
I think your solution is a bit more elegant than what I came up with, however I am getting the following: Adding some debug prints, it's trying to subtract wait_time: 33 from next_tick: 83 and failing in spectacular fashion. Since there is already a check for next_tick >= wait_time, swapping the order resolves this panic. From a few minutes of testing, the FPS is remarkably stable, however it misses almost every keyboard input using the keyboard example and my own project.
Indeed that makes sense, apologies if I was stating the obvious! :) |
Looking more closely, it looks like TICK_TYPE is still being set to Poll which only gets overridden with WaitUntil on the 'requested' Poll timeframe. This explains why the input is so delayed. I removed the control flow declaration on like line 181 entirely and that solved the input latency, however it looks like the next_tick variable is never getting reset meaning it gets slower and slower until a few frames in, nothing ticks without input. |
Trying the latest |
After a bit of additional research, it also looks like Winit expects OnDrawRequested to be used for static GUI's while MainEventsCleared is intended for games that are redrawing regularly. There has been some discussion with Bevy and that's the path they are leaning towards anyway. |
I just pushed a couple of commits that work really well on my Windows system (I'll get to Linux later today - have publisher meetings). There are two major changes:
On Windows at least, I see CPU usage in the task manager remain constant while I zoom the window around or resize it like crazy. |
On Mac, |
I just pushed a commit that significantly changes the
If that doesn't do the trick, I'm going to have to find a Mac and a profiler. |
Thank you so much for your help!
|
I'm beginning to think that The result is kinda alarming:
In other words, even though I only set the timer once - it ran over and over again as fast as it could! Peeking at |
…eeded in cutting CPU usage from 12% to 4% on hello_terminal, and 18% to about 2% on dwarfmap.
Even stranger, moving the control flow command to the top and using |
With the latest change, |
It definitely sounds like a good idea to make a simpler testbed, but that'll have to wait a bit - I have limited time. What FPS does |
When I cap it to 30, it's similar, 21-25. |
Thank you. So it's behaving similarly - that means I can do the hard part of trying to make the numbers right. The uncapped CPU is going to be higher than it should, the library itself is quite inefficient at repeatedly redrawing the whole console. That part is on my "for the future" list. |
When capped at 30, I'm seeing it around 20-21 FPS, however when rapid keystrokes or mouse movements occur, it locks at 30, sometimes 31. So there's certainly progress here... I'm also trying to tear about Winit to see if something is broken there as well. |
…s specified. Set the benchmark examples to set a higher FPS, which is what you should do if you want to go really fast.
The latest commit takes a different approach. My testing showed that So I grabbed the I then went and set the default FPS cap to 30, and adjusted the benchmark examples to request 120 instead - so they still go really fast. I'm hoping this will work as well on other platforms. The timer precision explains why my original code (which had a thread sleep) was so flakey. |
Happy to report that this version is also running very well in a virtual Ubuntu (what I have handy). CPU usage is way down, and frame-rate is about right (not perfect, but my VirtualBox setup on this PC is also mind-numbingly slow). My virtual hackintosh for testing is refusing to boot at all, so untested there. I really need to pickup a Mac Mini or something for testing. |
Apologies I've been so quiet, work has been hectic but I've been following along and doing research/testing fix ideas on my own as well with little success. I can say the latest 228 looks to be locked at 30 for hello_terminal, but drops 1-2 fps during mouse movement/input, so nearly perfect. Also, the input_harness is locked at about 30, but also handling keyboard inputs without noticeable latency. Finally, and almost as importantly as the input latency, CPU usage is around 2%, down from 10% previously, so great work and thank you so much for helping with this mind-bending issue @thebracket @singalen ! 👍 |
Thank you! (And don't worry about being quiet; I have long periods of work keeping me busy). I'm not sure what I can about the small drop from input (downside of sleeping, the whole input thread is waiting - so it doesn't know to wake up for events and processes them all at once when tick-time arrives) - so I'll call this good enough for now and start getting it merged into the mainline. I have quite a few other issues I want to look at before rolling out the next crate version. Thanks for all your help, glad we've got the CPU under control! |
Ok, this is merged and passing all the tests I threw at it. Most importantly, the Hands-on Rust and roguelike tutorials work with it. In particular, the final dungeon crawler example from Hands-on Rust drops CPU usage from 12% (I have 8 cores, so basically pegging one core) to 1.5%. I'll go ahead and call this a win and close the issue. :-) |
Looks like on Mac my game is running the main loop as fast as it can.
What can I do about it?
How can I help to diagnose it?
Ideally, it should only redraw in response to keyboard and, optionally, mouse events.
The text was updated successfully, but these errors were encountered: