2008年1月7日月曜日

powerdで最小の周波数を設定

FreeBSD では powerd を使うと CPU の周波数を自動的に変化させることができる. しかし, 標準のまま使うと, 周波数が低くなりすぎるようで, 全体的に反応が遅くなるので, 普段は使っていなかった. なんとなく気が向いたので, src/usr.sbin/powerd/powerd.c をちょっといじってみた.

使い方としては, -x オプションで最小の周波数を指定すると, powerd はその周波数以下には下げないようになる. それ以外は変わらない. 現在 "-x 1600" にして使っている.

(追記) これと同様のことは sysctl でも実現できます. 続き

--- powerd.c.orig 2008-01-07 21:57:28.000000000 +0900
+++ powerd.c 2008-01-07 22:15:45.000000000 +0900
@@ -95,6 +95,9 @@
static int apm_fd;
static int exit_requested;

+/* Minimum CPU Frequency */
+static int cpu_min_freq = 0;
+
static int
read_usage_times(long *idle, long *total)
{
@@ -249,7 +252,7 @@
{

fprintf(stderr,
-"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
+"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile] [-x min_freq]\n");
exit(1);
}

@@ -277,7 +280,7 @@
if (geteuid() != 0)
errx(1, "must be root to run");

- while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != EOF)
+ while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:x:v")) != EOF)
switch (ch) {
case 'a':
parse_mode(optarg, &mode_ac, ch);
@@ -317,6 +320,9 @@
case 'v':
vflag = 1;
break;
+ case 'x':
+ cpu_min_freq = atoi(optarg);
+ break;
default:
usage();
}
@@ -459,7 +465,10 @@
warn("read_usage_times() failed");
continue;
}
-
+ if(curfreq < cpu_min_freq){
+ set_freq(cpu_min_freq);
+ curfreq = cpu_min_freq;
+ }
/*
* If we're idle less than the active mark, bump up two levels.
* If we're idle more than the idle mark, drop down one level.
@@ -482,7 +491,7 @@
warn("error setting CPU frequency %d",
freqs[i]);
} else if (idle > (total * cpu_idle_mark) / 100 &&
- curfreq > freqs[numfreqs - 1]) {
+ curfreq > freqs[numfreqs - 1] && freqs[i + 1] >= cpu_min_freq) {
i++;
if (vflag) {
printf("idle time > %d%%, decreasing clock"

2 件のコメント:

匿名 さんのコメント...

通りすがりです。
タイミング的にはかなり逃していますが。
sysctlで、debug.cpufreq.lowest に値をセットすれば、ほぼ同様な事が実現可能のようです。

ztw さんのコメント...

匿名さん, コメントありがとうございます. おっしゃる通り sysctl でも同様のことができます. そのことは一応続きの記事に書いていたのですが, こちらにもリンクを張っておくべきでしたね. 修正しました.