aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--devices/thinkpad-fan.cpp13
-rw-r--r--main.cpp9
-rw-r--r--parameters/learn.cpp87
-rw-r--r--process/do_process.cpp2
5 files changed, 83 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index cf2086d..d0cf28a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
all: powertop graphparameters
-CFLAGS += -Wall -O0 -g
-CPPFLAGS += -Wall -O0 -g
-CXXFLAGS += -Wall -O0 -g
+CFLAGS += -Wall -O2 -g -fno-omit-frame-pointer
+CPPFLAGS += -Wall -O2 -g -fno-omit-frame-pointer
+CXXFLAGS += -Wall -O2 -g -fno-omit-frame-pointer
OBJS := lib.o main.o
OBJS += cpu/cpu.o cpu/abstract_cpu.o cpu/cpu_linux.o cpu/cpu_core.o cpu/cpu_package.o cpu/intel_cpus.o cpu/cpudevice.cpp
OBJS += perf/perf.o perf/perf_bundle.o
diff --git a/devices/thinkpad-fan.cpp b/devices/thinkpad-fan.cpp
index 11b7284..286cfe0 100644
--- a/devices/thinkpad-fan.cpp
+++ b/devices/thinkpad-fan.cpp
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
+#include <math.h>
#include "../lib.h"
@@ -66,13 +67,21 @@ double thinkpad_fan::power_usage(struct result_bundle *result, struct parameter_
double utilization;
power = 0;
- factor = get_parameter_value("thinkpad-fan", bundle);
utilization = get_result_value("thinkpad-fan", result);
utilization = utilization - 50;
if (utilization < 0)
utilization = 0;
- power += utilization * factor / 100.0;
+
+ factor = get_parameter_value("thinkpad-fan-sqr", bundle);
+ power += factor * pow(utilization / 100.0, 2);
+
+ factor = get_parameter_value("thinkpad-fan", bundle);
+ power -= utilization * factor / 100.0;
+
+ if (power <= 0.0)
+ power = 0.0;
+
return power;
}
diff --git a/main.cpp b/main.cpp
index cb67966..a2c51e9 100644
--- a/main.cpp
+++ b/main.cpp
@@ -42,7 +42,7 @@ void one_measurement(int seconds)
global_joules_consumed();
compute_bundle();
- report_devices();
+// report_devices();
store_results();
end_cpu_data();
}
@@ -85,16 +85,16 @@ int main(int argc, char **argv)
- learn_parameters(600);
+ learn_parameters(50);
dump_parameter_bundle();
save_parameters("saved_parameters.powertop");
/* first one is short to not let the user wait too long */
one_measurement(5);
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 25; i++) {
one_measurement(20);
- learn_parameters(10);
+ learn_parameters(15);
}
@@ -103,6 +103,7 @@ int main(int argc, char **argv)
end_cpu_data();
save_all_results("saved_results.powertop");
+ save_parameters("saved_parameters.powertop");
learn_parameters(500);
save_parameters("saved_parameters.powertop");
printf("Final estimate:\n");
diff --git a/parameters/learn.cpp b/parameters/learn.cpp
index f5556e9..e1e248c 100644
--- a/parameters/learn.cpp
+++ b/parameters/learn.cpp
@@ -35,6 +35,17 @@ static int random_disturb(int retry_left)
return 0;
}
+static int try_zero(double value)
+{
+ if (value > 0.01)
+ if ( (rand() % 100) == 1)
+ return 1;
+
+ if ( (rand() % 5) == 1)
+ return 1;
+ return 0;
+}
+
static unsigned int previous_measurements;
/* leaks like a sieve */
@@ -44,6 +55,8 @@ void learn_parameters(int iterations, const char *pattern)
double best_score = 10000000000000000.0;
map<string, double>::iterator it;
int retry = iterations;
+ string prevparam = "";
+ int locked = 0;
// if (past_results.size() == previous_measurements)
// return;
@@ -81,46 +94,56 @@ void learn_parameters(int iterations, const char *pattern)
while (retry--) {
int changed = 0;
string bestparam;
- double newvalue;
+ double newvalue = 0;
+ double orgscore;
bestparam = "";
calculate_params(best_so_far);
- best_score = best_so_far->score;
+ orgscore = best_score = best_so_far->score;
for (it = best_so_far->parameters.begin(); it != best_so_far->parameters.end(); it++) {
double value, orgvalue;
+ string param;
+
+ param = it->first;
if (pattern) {
- if (strstr(it->first.c_str(), pattern) != NULL) {
+ if (strstr(param.c_str(), pattern) != NULL) {
continue;
}
}
- orgvalue = value = best_so_far->parameters[it->first];
+// if (locked) {
+// param = prevparam;
+// if (it != best_so_far->parameters.begin())
+// break;
+// }
+
+ orgvalue = value = best_so_far->parameters[param];
if (value <= 0.001) {
value = 0.1;
} else
value = value * (1 + delta);
- if (it->first == "base power" && value > min_power)
+ if (param == "base power" && value > min_power)
value = min_power;
- if (it->first == "base power" && orgvalue > min_power)
+ if (param == "base power" && orgvalue > min_power)
orgvalue = min_power;
if (value > 5000)
value = 5000;
-// printf("Trying %s %4.2f -> %4.2f\n", it->first.c_str(), best_so_far->parameters[it->first], value);
- best_so_far->parameters[it->first] = value;
+// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), best_so_far->parameters[param], value);
+ best_so_far->parameters[param] = value;
calculate_params(best_so_far);
if (best_so_far->score < best_score || random_disturb(retry)) {
best_score = best_so_far->score;
newvalue = value;
- bestparam = it->first;
+ bestparam = param;
changed++;
}
@@ -129,42 +152,58 @@ void learn_parameters(int iterations, const char *pattern)
if (value < 0.0001)
value = 0.0;
+ if (try_zero(value))
+ value = 0.0;
+
if (value > 5000)
value = 5000;
-// printf("Trying %s %4.2f -> %4.2f\n", it->first.c_str(), orgvalue, value);
- best_so_far->parameters[it->first] = value;
+// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), orgvalue, value);
- calculate_params(best_so_far);
- if (best_so_far->score + 0.00001 < best_score || random_disturb(retry)) {
- best_score = best_so_far->score;
- newvalue = value;
- bestparam = it->first;
- changed++;
+ if (orgvalue != value) {
+ best_so_far->parameters[param] = value;
+
+ calculate_params(best_so_far);
+
+ if (best_so_far->score + 0.00001 < best_score || (random_disturb(retry) && value > 0.0)) {
+ best_score = best_so_far->score;
+ newvalue = value;
+ bestparam = param;
+ changed++;
+ }
}
- best_so_far->parameters[it->first] = orgvalue;
+ best_so_far->parameters[param] = orgvalue;
}
if (!changed) {
double mult;
- mult = 0.8;
- if (iterations < 25)
- mult = 0.5;
- delta = delta * mult;
+
+ if (!locked) {
+ mult = 0.8;
+ if (iterations < 25)
+ mult = 0.5;
+ delta = delta * mult;
+ }
+ locked = 0;
+ prevparam = "";
} else {
if (debug_learning) {
printf("Retry is %i \n", retry);
printf("delta is %5.4f\n", delta);
printf("Best parameter is %s \n", bestparam.c_str());
- printf("Changing score from %4.3f to %4.3f\n", best_so_far->score, best_score);
+ printf("Changing score from %4.3f to %4.3f\n", orgscore, best_score);
printf("Changing value from %4.3f to %4.3f\n", best_so_far->parameters[bestparam], newvalue);
}
best_so_far->parameters[bestparam] = newvalue;
+ if (prevparam == bestparam)
+ delta = delta * 1.1;
+ prevparam = bestparam;
+ locked = 1;
}
- if (delta < 0.001)
+ if (delta < 0.001 && !locked)
break;
}
diff --git a/process/do_process.cpp b/process/do_process.cpp
index cc178ec..947c53a 100644
--- a/process/do_process.cpp
+++ b/process/do_process.cpp
@@ -199,7 +199,7 @@ void perf_process_bundle::handle_trace_point(int type, void *trace, int cpu, uin
/* start new process */
new_proc->schedule_thread(time, sw->next_pid);
- if (strncmp(sw->next_comm,"migration/", 10) && strncmp(sw->next_comm,"kworker/", 8) ) {
+ if (strncmp(sw->next_comm,"migration/", 10) && strncmp(sw->next_comm,"kworker/", 8) && strncmp(sw->next_comm, "kondemand/",10)) {
if (sw->next_pid) {
/* If someone woke us up.. blame him instead */
if (new_proc->waker) {