Date: Sun, 20 Mar 2005 23:13:28 -0800 From: Nate Lawson <nate@root.org> To: Kevin Oberman <oberman@es.net> Cc: acpi@freebsd.org Subject: Re: Issues with powerd Message-ID: <423E7418.5060609@root.org> In-Reply-To: <20050309192938.23DCB5D07@ptavv.es.net> References: <20050309192938.23DCB5D07@ptavv.es.net>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------040509050201070607060202 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------040509050201070607060202 Content-Type: text/plain; name="powerd.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="powerd.c.diff" 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) { --------------040509050201070607060202--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?423E7418.5060609>