powerd(8)
Eric Anderson
anderson at centtech.com
Mon Apr 18 07:40:50 PDT 2005
Bruno Ducrot wrote:
> On Mon, Apr 18, 2005 at 02:19:14PM +0200, Poul-Henning Kamp wrote:
>
>>In message <4263A33A.3030201 at centtech.com>, Eric Anderson writes:
>>
>>>Lukas Ertl wrote:
>>>
>>>There's been some discussion on the -mobile list (I believe) about
>>>this kind of thing before. I think powerd is currently running with
>>>a 'best shot' configuration, and I'm pretty sure that if anyone has
>>>a better algorithm in a patch form for people to try, I'm certain the
>>>good people with commit bits would easily commit a patched better version.
>>
>>I don't think a proportional approach will work in this case, the steps
>>are too far apart.
>>
>>I also think the switch to full speed is wrong. Such see-saw
>>algorithms waste far too much time decaying. A less steep flank
>>should be used.
>
>
> The full speed thing is right in almost case. When we ran the processor
> at lower speed, then we loose somehow the runpercent if running
> at full speed at previous window.
> Suppose for example we have those normalized performance
> states: 100% 66% 50%
> If we ran at 50% but read a 100% runpercent, then if we were running
> at full speed, we would got a 50% runpercent which is given by
> (runpercent * normalized_speed). Those far, we can only say actually
> that runpercent (at full speed) is in-between 50% and 100%. If, for
> example, the real runpercent (at full speed) is actually 50%,
> then we should stay at 50%, if its at 66%, we should set speed at 66%
> and so on. But we can only estimate a value of 50% in all cases.
>
> Therefore almost all algorithms will put the processor at full speed
> if an increase is detected.
> This work pretty well when the polling intervall is small
> (something between 40 or 50 milliseconds).
> In the case of powerd, the real trouble is maybe the polling interval
> and we should use an adaptive filter in order to fix this issue.
>
> The case when we detect to go down is less problematic because we are
> able to compute at least an accurate estimation of runpercent for
> the previous window.
>
Ok, I've attached my tweaks to PHK's adaptive. I run it like this:
/usr/sbin/powerd -a max -b adaptive2 -p 100 -r 20
Seems to do a pretty decent job at being responsive, yet gives me a longer
battery time than the default adaptive. Not perfect, but still better I think..
(Thanks PHK for a quick patch!)
Eric
--
------------------------------------------------------------------------
Eric Anderson Sr. Systems Administrator Centaur Technology
A lost ounce of gold may be found, a lost moment of time never.
------------------------------------------------------------------------
-------------- next part --------------
--- powerd.c Mon Apr 18 09:26:49 2005
+++ powerd.c-new Mon Apr 18 09:18:30 2005
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.sbin/powerd/powerd.c,v 1.6 2005/04/10 20:42:55 njl Exp $");
+__FBSDID("$FreeBSD: src/usr.sbin/powerd/powerd.c,v 1.6 2005/04/10 20:42:55 njl Exp $");
#include <err.h>
#include <fcntl.h>
@@ -51,6 +51,7 @@
enum modes_t {
MODE_MIN,
MODE_ADAPTIVE,
+ MODE_ADAPTIVE2,
MODE_MAX,
};
@@ -229,6 +230,8 @@
*mode = MODE_MAX;
else if (strcmp(arg, "adaptive") == 0)
*mode = MODE_ADAPTIVE;
+ else if (strcmp(arg, "adaptive2") == 0)
+ *mode = MODE_ADAPTIVE2;
else
errx(1, "bad option: -%c %s", (char)ch, optarg);
}
@@ -416,6 +419,44 @@
/* Adaptive mode; get the current CPU usage times. */
if (read_usage_times(&idle, &total))
err(1, "read_usage_times");
+
+ if (mode == MODE_ADAPTIVE2) {
+ for (i = 0; i < numfreqs - 1; i++) {
+ if (freqs[i] == curfreq)
+ break;
+ }
+ if (idle < (total * cpu_running_mark) / 100 &&
+ curfreq < freqs[0]) {
+ i -= 4;
+ if (i < 0)
+ i = 0;
+ if (vflag) {
+ printf("idle time < %d%%, increasing clock"
+ " speed from %d MHz to %d MHz\n",
+ cpu_running_mark, curfreq, freqs[i]);
+ }
+ if (set_freq(freqs[i]))
+ err(1, "error setting CPU frequency %d", freqs[i]);
+
+ } else if (idle > (total * cpu_idle_mark) / 100 &&
+ curfreq > freqs[numfreqs - 1]) {
+ i++;
+ i++;
+ i++;
+ if (vflag) {
+ printf("idle time > %d%%, decreasing clock"
+ " speed from %d MHz to %d MHz\n",
+ cpu_idle_mark, curfreq, freqs[i]);
+ }
+ if (set_freq(freqs[i]))
+ err(1, "error setting CPU frequency %d", freqs[i]);
+ usleep(poll_ival);
+ } else if (curfreq == freqs[0]) {
+ usleep(poll_ival);
+ usleep(poll_ival);
+ }
+ continue;
+ }
/*
* If we're idle less than the active mark, jump the CPU to
More information about the freebsd-current
mailing list