Idle CPU burn
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).
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
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
@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)
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. :)
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
glfwWaitEvents();
that looks interesting, thanks a lot!