Issues with powerd
Nate Lawson
nate at root.org
Sun Mar 20 23:13:33 PST 2005
Kevin Oberman wrote:
> I have finally had a little time to play with powerd and I didn't find
> adaptive mode worked too well for me on my T30 running a Gnome desktop.
>
> The effect of running powerd was to move the freq in a rapid sawtooth
> dropping quickly to 150 MHz and them jumping back to 1800 and
> repeating. If the CPU was busy, the low point of the sawtooth would be
> elevated to 300or 600, but the basic pattern was constant oscillation.
>
> I looked at the source and decided that two things were wrong.
>
> 1. Dropping to half of the initial CPU speed was to a good choice. The
> drop is speed was too quick and it resulted in reducing the number of
> CPU performance levels to a small number instead of the 15 that should
> be available.
>
> 2. When the CPU got busier, jumping all the way to full speed was
> excessive and would always result in the sawtooth oscillation.
>
> I modified powerd to increase or decrease cpufreq in single steps instead
> of jumping (in either direction) and lowered DEFAULT_ACTIVE_PERCENT to
> 75. This results in a system that wanders between 150 and 450 when idle
> and climbs to full speed when under load.
>
> I suspect this is sub-optimal, but I think it's a lot better then the
> current operation. I will try to spend some time tweaking the algorithm
> a bit to see what makes things run best (for my personal idea of "best".
>
> Ideally, I'd like to see it stay constant an an idle or constantly
> loaded system and I suspect that I will need to add hysteresis to get
> there.
Please try the attached patch. It delays IDLE_DECAY_COUNT poll cycles
before starting the descent to slowest speed. The current value of 4
waits a second. This should slow the "sawtooth" issue. Once it starts
the decay, it drops one setting per poll interval. It still jumps
immediately to full speed once below 80% idle but I think this will
solve your issue. If not, try tweaking IDLE_DECAY_COUNT.
--
Nate
-------------- next part --------------
Index: powerd.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/powerd/powerd.c,v
retrieving revision 1.4
diff -u -r1.4 powerd.c
--- powerd.c 27 Feb 2005 01:58:49 -0000 1.4
+++ powerd.c 21 Mar 2005 07:10:16 -0000
@@ -46,6 +46,7 @@
#define DEFAULT_ACTIVE_PERCENT 80
#define DEFAULT_IDLE_PERCENT 90
#define DEFAULT_POLL_INTERVAL 500
+#define IDLE_DECAY_COUNT 4
enum modes_t {
MODE_MIN,
@@ -237,7 +238,7 @@
main(int argc, char * argv[])
{
long idle, total;
- int curfreq, *freqs, i, numfreqs;
+ int curfreq, *freqs, i, idle_count, numfreqs;
int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag;
size_t len;
@@ -246,7 +247,7 @@
cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
cpu_idle_mark = DEFAULT_IDLE_PERCENT;
poll_ival = DEFAULT_POLL_INTERVAL;
- vflag = 0;
+ vflag = idle_count = 0;
apm_fd = -1;
while ((ch = getopt(argc, argv, "a:b:i:n:p:r:v")) != EOF)
@@ -380,11 +381,13 @@
/*
* If we're idle less than the active mark, jump the CPU to
* its fastest speed if we're not there yet. If we're idle
- * more than the idle mark, drop down to the first setting
- * that is half the current speed (exponential backoff).
+ * more than the idle mark, drop down to the next lower
+ * setting after a short delay to be sure we're really idle.
*/
- if (idle < (total * cpu_running_mark) / 100 &&
- curfreq < freqs[0]) {
+ if (idle < (total * cpu_running_mark) / 100) {
+ idle_count = 0;
+ if (curfreq == freqs[0])
+ continue;
if (vflag) {
printf("idle time < %d%%, increasing clock"
" speed from %d MHz to %d MHz\n",
@@ -395,8 +398,11 @@
freqs[0]);
} else if (idle > (total * cpu_idle_mark) / 100 &&
curfreq > freqs[numfreqs - 1]) {
+ if (++idle_count < IDLE_DECAY_COUNT)
+ continue;
+
for (i = 0; i < numfreqs - 1; i++) {
- if (freqs[i] <= curfreq / 2)
+ if (freqs[i] < curfreq)
break;
}
if (vflag) {
More information about the freebsd-acpi
mailing list