-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Added power saving mode (docking branch) #4076
base: docking
Are you sure you want to change the base?
Conversation
Done. (I didn’t realize workflows now needed approval!) |
You can thank crypto for that! https://github.blog/2021-04-22-github-actions-update-helping-maintainers-combat-bad-actors/ |
any improvement regarding the cpu usage? really, it's ages that it's working, should be merged... without cpu usage reduction what the point of having a blast fast GUI when even a calc app consume 30% cpu???? how can you imagine having 30+ imgui based app running each consuming 30% CPU? |
That is not in line with my own observations. For the demo window, I typically get on Linux without this MR:
Drops to 0% with my energy branch. @rokups Some examples/backends/platforms support a check if a window is visible, and if the window is not visible don't draw. Is your window visible when you look at the CPU usage? |
It is visible. That reeding depends on some settings. When value is "scaled to 100%" it shows 0.0%, when scaling is disabled it shows 2%. Probably also depends on CPU.. |
For simple UI that fixed cost often come more the swap for which mileage may vary depending on drivers/gpu/os.
Dear ImGui was initially designed as a game overlay so this hasn’t been a priority for a while but I agree this is a feature we should be looking at merging, we will eventually, just juggling with tasks.
|
Hi,
On my laptop, for the demo window, on master branch from ocornut, synced
today (321b84f)
I get about 10-12% CPU usage glfw + opengl3 example;
the issue is that this CPU usage is ALWAYS whatever the state of the window
:
- the window can be obscured
- the window can be reduced to tray
- the window can be on another workspace
the window has not a single event and still consume CPU
open 10 demo window, you killed the CPU....
so imagine a whole desktop with a 10 text editors..... that kills a i7
cpu.... not sure it's something everyone wants...
Le mar. 31 août 2021 à 11:57, omar ***@***.***> a écrit :
… For simple UI that fixed cost often come more the swap for which mileage
may vary depending on drivers/gpu/os.
Dear ImGui was initially designed as a game overlay so this hasn’t been a
priority for a while but I agree this is a feature we should be looking at
merging, we will eventually, just juggling with tasks.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#4076 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJUDLRFOXLUXPYKZ5VBPUETT7SRQPANCNFSM43SX6NZQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
I tried to cherry-pick again this PR onto the latest docking branch. You can see the results in the commits here (this is a branch that cherry picks and adapts your changes) Summary:
Additional notes:
Benchmarks:On my Mac (MacBook Pro Intel 2019), I have the following results, when using the backends As you see, without the powersave changes the GPU jumps to 24% (and this causes my mac to become very hot, very quickly)
|
…h docking_powersave See PR ocornut/imgui#4076 This PR was adapted to imgui docking version of March 2022 here in the repo https://github.com/pthom/imgui
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use the SDL backend. I have noticed that no frames are rendered whatsoever if no events occur, which is unintuitive, if the end user is waiting for a job to finish and then display a result or something and they are not moving the mouse. This could be circumvented by only using waitforevent if a condition is met. let's say a should_wait variable, but a better way would be to still render a few frames every second. Let's say 2. That way there is no need for the ImGui::GetEventWaitingTime() function you have added, or it should at least be modified, so that infinity could not be returned. Another way would be to just specify waiting time to 0.5s if window isn't hidden, and remove waiting_time_ms; change the value in the function call to 500.
For an alternative approach, you could also look at https://github.com/ocornut/imgui/wiki/Implementing-Power-Save,-aka-Idling-outside-of-ImGui |
I've implemented something to reduce GPU usage for my desktop application, which may have GL views embedded via a render list callback (AddCallback) and some other text controls which may want to be updated at high frequency. Before - Free-running at screen refresh rate of 165Hz:
Before - Free-running at screen refresh rate of 60Hz:
Fast Update Mode is a game-like mode where at least some parts of my app need 60Hz updates. For both of my adaptations, I chose to lock the maximum update rate to 60Hz in the app as well as with the screen. With simple event updates and additional full-screen rendering in Fast Update Mode:
With simple event updates and partial rendering and on-demand UI rendering:
The last adaptation uses a modified rendering backend implementation that allows me to draw only parts of the screen. Just for fun, the same last adaptation but at 165Hz screen, with fast update mode rendering at ~120Hz:
Note that the GL views in this tests were trivially simple, so only the fillrate should have affected the results. In conclusion:
I have not tested yet if doing a ImGui New Frame + partial render of areas that changed is a good compromise, but maybe it will be, since the NewFrame (e.g., purely CPU work) did not affect the power draw much for me, the GPU dominated the power draw. While the power draw savings seen here don't seem like much, they are the difference between the laptop staying quiet and the fans being on full blast for me. Here's my final render loop: ui.requireUpdates = 3;
while (!glfwWindowShouldClose(ui.window))
{
auto now = sclock::now();
ui.deltaTime = dt(ui.renderTime, now)/1000.0f;
ui.renderTime = now;
if (ui.requireUpdates)
{
ui.requireUpdates--;
ui.UpdateUI();
ui.RenderUI(true);
}
else if (ui.requireRender)
{ // Render parts of the screen with OnDemand rendered items
ui.RenderUI(false);
}
ui.requireRender = false;
long targetIntervalUS = 1000000/60; // RenderUI (glfwSwapBuffer) might force the frequency down to display refresh rate
long curIntervalUS = dtUS(ui.renderTime, sclock::now());
if (curIntervalUS < targetIntervalUS)
{
std::this_thread::sleep_for(std::chrono::microseconds(targetIntervalUS-curIntervalUS));
}
glfwPollEvents();
while (!ui.requireRender && ui.requireUpdates == 0
&& context->InputEventsQueue.empty())
{
glfwWaitEventsTimeout(0.5f/1000.0f);
}
if (!context->InputEventsQueue.empty())
ui.requireUpdates = std::max(ui.requireUpdates, 3);
} with UpdateUI just being ImGui's stack from NewFrame to Render, and RenderUI: void RenderUI(bool fullUpdate)
{
if (fullUpdate)
{
// Render 2D UI with callbacks at appropriate places for 3D GL
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
else
{
// Render areas of the screen with on-demand items - rest will be discarded
for (auto &onDemandState : onDemandStack)
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData(), onDemandState.clipMin, onDemandState.clipMax);
}
glfwMakeContextCurrent(window);
glfwSwapBuffers(window);
} The label I mentioned is drawn on-demand like this (which internally uses AddCallback): AddOnDemandText("Frame 00000", [](const ImDrawList* dl, const ImDrawCmd* dc)
{
RenderOnDemandText(*(OnDemandState*)dc->UserCallbackData, "Frame %d", GetApp().frameNum);
});
// Instead of:
//ImGui::Text("Frame %d", GetApp().frameNum); And the GL views are setup something like this: ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddCallback([](const ImDrawList* dl, const ImDrawCmd* dc)
{
glViewport(...)
glScissor(...);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render GL Scene
}, nullptr);
draw_list->AddCallback(ImDrawCallback_ResetRenderState, nullptr);
MarkOnDemandArea(ImGui::GetCurrentWindowRead()->InnerRect); Finally, the patch for the imgui_impl_opengl3.cpp aswell as the custom on-demand rendering code is attached. UPDATE: Moved to a gist: https://gist.github.com/Seneral/b4b34a283539938869cd10b2d065a88c |
…#7556, #5116 , #4076, #2749, #2268) currently: ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags_TryToAvoidRefresh); - This is NOT meant to replace frame-wide/app-wide idle mode. - This is another tool: the idea that a given window could avoid refresh and reuse last frame contents. - I think it needs to be backed by a careful and smart design overall (refresh policy, load balancing, making it easy and obvious to user). - It's not there yet, this is currently a toy for experimenting. My other issues with this: - It appears to be very simple, but skipping most of Begin() logic will inevitably lead to tricky/confusing bugs. Let's see how it goes. - I don't like very much that this opens a door to varying inconsistencies - I don't like very much that it can lead us to situation where the lazy refresh gets disabled in bulk due to some reason (e.g. resizing a dock space) and we get sucked in the temptation to update for idle rather than update for dynamism.
This is the docking/viewport branch version of the power saving mode implemented in #2749. That PR has a lot of background regarding how that feature came to be.
The next steps of the plan are:
Make sure I did not screw up the cherry-pick