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);
 }
 

Reply via email to