High CPU usage with Multiple Editor Tabs Mode

I compile ART myself on Ubuntu Linux 20.04. I’ve seen this issue for some time, it also happens with Rawtherapee but to a lesser degree. I just now saw the issue with ART 1.5.4-47-g3ccefd613.

In Multiple Editor Tabs Mode if I open a large number of Nikon NEF files, 10 for example, so I have 10 tabs, if I then change “input focus” from the ART window to a terminal window I see the CPU usage of ART go up, then if I click back on the ART window to again give ART “input focus” I again see the ART CPU usage go up. How much? For 10 tabs changing focus to the terminal window causes ART to use 4 seconds of CPU on my AMD 2700x 8 core 16 thread CPU. I have 32 GB of RAM and RAM usage is way below that limit plus when I check swap none is being used. When I then change focus back to ART I see another 3 seconds of CPU usage for a total of 7 seconds for each “input focus cycle”. If I close some of the tabs so I go from 10 tabs to say 3 then repeat the cycle of changing focus then the CPU usage does go down but its still about 2 or 3 seconds. If I close more tabs to go down to 1 tab and repeat the cycle the CPU usage again decreases but its still about 1 second. From the terminal window if I run “ps -lLfp PID” where PID is the ART process then I can see all the threads the ART process has and I also see the CPU usage is all in the main thread during this focus cycling, not the child threads. If I compile ART with “-DWITH_BENCHMARK=ON” I see messages when the 10 images open in the 10 tabs but nothing when I change focus back and forth, so apparently ART is not “re processing” the images. I downloaded a “gstack” command which uses gdb to print the stack trace of a given PID and all its children. When I run that gstack at the times of ART CPU usage when changing focus I see the main thread doing this (ART is now compiled as TYPE=RelWithDebugInfo):

Thread 1 (Thread 0x7fe66fb90e80 (LWP 49643)):
#0 0x00007fe67545f390 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#1 0x00007fe67545f6a6 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#2 0x00007fe67546168e in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#3 0x00007fe67545b5aa in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#4 0x00007fe6755b70bd in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#5 0x00007fe675469201 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#6 0x00007fe675456a55 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#7 0x00007fe675455874 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#8 0x00007fe675456555 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#9 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#10 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#11 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#12 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#13 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#14 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#15 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#16 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#17 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#18 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#19 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#20 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#21 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#22 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#23 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#24 0x00007fe6754565ab in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#25 0x00007fe67543c766 in () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#26 0x00007fe675170a56 in () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#27 0x00007fe67518fb28 in g_signal_emit_valist () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#28 0x00007fe6751900d3 in g_signal_emit () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#29 0x00007fe675202f16 in () at /lib/x86_64-linux-gnu/libgdk-3.so.0
#30 0x00007fe6751ecf4d in () at /lib/x86_64-linux-gnu/libgdk-3.so.0
#31 0x00007fe675085a28 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#32 0x00007fe675084e8e in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#33 0x00007fe675085240 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007fe675085533 in g_main_loop_run () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007fe67550f37d in gtk_main () at /lib/x86_64-linux-gnu/libgtk-3.so.0
#36 0x00007fe674944258 in Gtk::Main::run(Gtk::Window&) () at /lib/x86_64-linux-gnu/libgtkmm-3.0.so.1
#37 0x000055fa2d02f395 in main ()

So again it seems the CPU usage during focus change is not in ART code but in the GTK 3 libraries. I know next to nothing about GTK but I am wondering why simply changing input focus causes GTK to use a lot of ART CPU usage and that amount changes depending on the number of tabs open in ART. As I said at the start I see a similar pattern with Rawtherapee but the amount of CPU usage is roughly half when 10 tabs are open in Rawtherapee using the same 10 Nikon NEF images. I also tried deleting all the existing .arp and .pp3 files for those 10 images and the same focus cycling CPU usage happens.

I should also mention that the CPU usage is all in “user” time and not “sys” time, its not a ton of operating system calls.

So the bottom line is I am wondering where this CPU usage is coming from and can the ART code be “tweaked” to reduce that?

Then again I may just be crazy. :slight_smile:

Thanks for the detailed analysis. My guess is this is due to the excessive number of X resources being created (on windows, there’s a hard limit and you can’t even create that many tabs). The fact that art is worse than RT might just be because art uses more widgets…
If I’m correct, the solution is very simple to describe: just switch to a model/view paradigm for managing the editor tabs, instead of duplicating all the widgets. However, this is probably a few man-days of work, which (given my constraints) translate in weeks if not months of elapsed time to complete. Something definitely interesting, but only after 1.6 is out.

Thanks for the reply. Sadly I am unable to help with any GTK coding changes, but if you do get around to trying a “new paradigm” in the future, I would be happy to help test. Thanks for all you do.