ledit icon indicating copy to clipboard operation
ledit copied to clipboard

Idle CPU burn

Open kennylevinsen opened this issue 3 years ago • 6 comments

With a release build of 75c88f81ab939d27ca604d26d7a29e791965723c, I am observing 3.2% idle CPU burn on a random old Intel desktop CPU.

The test was made under sway (wayland), with the window visible with no content (entirely fresh window). In this situation, the editor should be completely idle with nothing to process or to draw.

I unfortunately see this quite often in new text editors, and it is usually caused by event loop issues (e.g. poll with timeout or use of frameworks that busy poll for events).

kennylevinsen avatar Mar 01 '22 12:03 kennylevinsen

Thanks on the feedback!

Ledit doesn't use any "frameworks" besides glfw which abstracts the window registration at the window manager since i care a lot about my stuff being as cross platform as possible. What you mean is the resources the render loop uses see main.cc Ledit already does aggressive caching on the highlighter to reduce load.

if you dont type anything, the main load happens here: https://github.com/liz3/ledit/blob/master/src/cursor.h#L1042-L1096 which calculates and returns a ptr to a vector for lines to render. everything else is preparing the buffer which is then uploaded to the gpu.

I did some benchmark a good while ago and the render loop runs sub 500 microseconds for empty files.

so here reducing the amount of paints or main loop iterations could help

liz3 avatar Mar 02 '22 02:03 liz3

Reducing on its own trivially(not taking 2 years of work) would work with: The gpu buffer could be saved and not altered unless action is taken: https://github.com/liz3/ledit/blob/master/src/main.cc#L374

But theres always to remember where do i need to redraw. actions history change text-change mouse click window resize window focus change

its def possible, il see if i can do it this weekend.

But ledit doesnt include frameworks, OpenGL is part of the OS.

The other two libraries freetype2/json arent frameworks, they are components solving specific problems i didnt want to do my self

liz3 avatar Mar 02 '22 03:03 liz3

@kennylevinsen could you possibly checkout https://github.com/liz3/ledit/tree/liz3/cached-state and let me know if this improves idle load for you? it cuts the entire render loop logic when not needed. (besides some unrelated winshit fixes i did)

liz3 avatar Mar 02 '22 03:03 liz3

The branch does remove the idle utilization when the window is unfocused (except for sporadic wakeups), but does not cure the CPU burn when the window is focused. Maybe it reduces utilization slightly, but it is still >2%.

Removing the sleep and swapping out glfwPollEvents with glfwWaitEvents drops the CPU utilization way down by sleeping until there are events from the window system to process (glfwWaitEventsTimeout can be used if ledit needs to wake up even if there are no events, such as to blink cursors):

diff --git a/src/main.cc b/src/main.cc
index bd99e94..b6aad93 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -346,11 +346,7 @@ int main(int argc, char** argv) {
     while (!glfwWindowShouldClose(window))
     {
       if(state.cacheValid) {
-        if(state.focused)
-          std::this_thread::sleep_for(std::chrono::milliseconds(1));
-        else 
-          std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        glfwPollEvents();
+        glfwWaitEvents();
         continue;
       }
       bool changed = false;
@@ -700,7 +696,7 @@ int main(int argc, char** argv) {
 
       glfwSwapBuffers(window);
       state.cacheValid = true;
-      glfwPollEvents();
+      glfwWaitEvents();
     }
     glfwTerminate();
   return 0;

When running ledit through wlhax/with WAYLAND_DEBUG=1, I also noticed that ledit is trying to update the mouse cursor (appearance, not location) continuously as long as it has pointer focus, which is weird. The above does not fix that.

But ledit doesnt include frameworks

GLFW (Graphics Library Framework) is what I referred to, which provides a window system abstraction and event loop. I was not implying a full fat toolkit like Gtk. :)

kennylevinsen avatar Mar 03 '22 21:03 kennylevinsen

When running ledit through wlhax/with WAYLAND_DEBUG=1, I also noticed that ledit is trying to update the mouse cursor (appearance, not location) continuously as long as it has pointer focus, which is weird. The above does not fix that.

thats weird, theres a mouse callback on click but nothing else, so that should be something internal by glfw...im not aware if theres a user side fix i can implement

liz3 avatar Mar 04 '22 01:03 liz3

glfwWaitEvents();

that looks interesting, thanks a lot!

liz3 avatar Mar 04 '22 01:03 liz3