hello, this is not actually a proposal for a commit but I'm playing with the frequency scaling code (that's the only part of the kernel I touched once and it's relatively simple and fun to work on).
I found in some cases that using the automatic scaling mode would produce poor results because the software required is at the threshold triggering the speed up and would give poor performance. The following change changes the automatic mode with a more performance oriented strategy. I made two changes: - instead of keeping the speed up for 5 cycles of 100ms, keep it 10 times which is 1 second instead of 500ms. This makes programs such as libreoffice more responsive for me. - instead of waiting to use 50% of all cores without triggering the other condition that is 70% use of a single core, speed up when the sum of used CPU time reach 1 CPU across n CPU. This condition triggers the speed up a lot more often than the current condition. I initially thought about reducing the checks to 200 or 300ms, but a given workload doesn't mean it will stay long, we need to check often to reduce the load when needed. I also gave a thought about involved the system load into this but I couldn't figure a simple case of it being meaningful. If the load rises, we certainly need high frequency, but then we would be stuck with it for too long time. I share this and will continue playing with the code, but if some people try it and find it to be useful, maybe we could think about different automatic modes like there are on other OSs? I'm thinking about powersave / performance modes. When using my laptop on battery, I will certainly prefer running the current code, but when connected to power, an automatic mode that provides more performance would make sense instead of switching to full performance and wasting electricity. I use a simple way to visualize the CPU frequency over time with ttyplot to draw a chart in a terminal. { while :; do sysctl -n hw.setperf ; sleep 1 ; done } | awk '{ print $1 ; fflush }' | ttyplot -t "CPU frequency in %" Index: sched_bsd.c =================================================================== RCS file: /home/reposync/src/sys/kern/sched_bsd.c,v retrieving revision 1.69 diff -u -p -r1.69 sched_bsd.c --- sched_bsd.c 9 Sep 2021 18:41:39 -0000 1.69 +++ sched_bsd.c 11 Sep 2021 12:55:42 -0000 @@ -582,6 +582,7 @@ setperf_auto(void *v) } total -= totalticks[j]; idle = ci->ci_schedstate.spc_cp_time[CP_IDLE] - idleticks[j]; + // speedup if at least one core idle time < 33% if (idle < total / 3) speedup = 1; alltotal += total; @@ -590,10 +591,13 @@ setperf_auto(void *v) totalticks[j] += total; j++; } - if (allidle < alltotal / 2) + // speedup if at least N-1 CPU is used in the result of the sum of the usage + // when one CPU this condition will never be met but it's OK + if (allidle < alltotal * (j-1) / j) speedup = 1; + // keep the speed up 10 for at least 10 checks if (speedup) - downbeats = 5; + downbeats = 10; if (speedup && perflevel != 100) { perflevel = 100; @@ -603,6 +607,7 @@ setperf_auto(void *v) cpu_setperf(perflevel); } + // one check occurs every 100ms timeout_add_msec(&setperf_to, 100); }