Re: powerd(8)

From: Eric Anderson <anderson_at_centtech.com>
Date: Mon, 18 Apr 2005 09:40:05 -0500
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.
------------------------------------------------------------------------

--- powerd.c	Mon Apr 18 09:26:49 2005
+++ powerd.c-new	Mon Apr 18 09:18:30 2005
_at__at_ -26,7 +26,7 _at__at_
  */
 
 #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>
_at__at_ -51,6 +51,7 _at__at_
 enum modes_t {
 	MODE_MIN,
 	MODE_ADAPTIVE,
+	MODE_ADAPTIVE2,
 	MODE_MAX,
 };
 
_at__at_ -229,6 +230,8 _at__at_
 		*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);
 }
_at__at_ -416,6 +419,44 _at__at_
 		/* 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
Received on Mon Apr 18 2005 - 12:40:50 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:32 UTC