aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Black <daniel.black@au1.ibm.com>2016-07-21 16:24:41 -0700
committerNivedita Swaminathan <nivedita.swaminathan@intel.com>2016-07-21 16:43:15 -0700
commitef79e2819ccac7c040d3203e66c1730a2c61c509 (patch)
tree9d3e9faf6edae8defe470e8e41c525d869a9a826
parent1636ce2c01d9bba024f2840f114b6c0554d05724 (diff)
Calculate the number of joules consumed over time
The *joules_consumed functions where returning power so renamed to reflect this. Calculate the joules used at intervals by multipling the instantaneous power by the time interval since the last measurement. Signed-off-by: Daniel Black <daniel.black@au1.ibm.com> v2: (Joe) Resolved a trivial hunk rejection in main.cpp +514 with 6696d4e5f2e ("enable --auto-tune without debugfs"); Acked-by added Acked-by: Joe Konno <joe.konno@intel.com>
-rw-r--r--src/calibrate/calibrate.cpp26
-rw-r--r--src/calibrate/calibrate.h2
-rw-r--r--src/devices/device.cpp11
-rw-r--r--src/main.cpp54
-rw-r--r--src/measurement/acpi.cpp2
-rw-r--r--src/measurement/acpi.h2
-rw-r--r--src/measurement/extech.cpp2
-rw-r--r--src/measurement/extech.h2
-rw-r--r--src/measurement/measurement.cpp31
-rw-r--r--src/measurement/measurement.h6
-rw-r--r--src/measurement/opal-sensors.cpp2
-rw-r--r--src/measurement/opal-sensors.h2
-rw-r--r--src/measurement/sysfs.h2
-rw-r--r--src/parameters/parameters.cpp2
-rw-r--r--src/parameters/parameters.h1
-rw-r--r--src/process/do_process.cpp8
16 files changed, 113 insertions, 42 deletions
diff --git a/src/calibrate/calibrate.cpp b/src/calibrate/calibrate.cpp
index 60ab892..745d544 100644
--- a/src/calibrate/calibrate.cpp
+++ b/src/calibrate/calibrate.cpp
@@ -261,7 +261,7 @@ static void cpu_calibration(int threads)
for (i = 0; i < threads; i++)
pthread_create(&thr, NULL, burn_cpu, NULL);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
stop_measurement = 1;
sleep(1);
}
@@ -276,7 +276,7 @@ static void wakeup_calibration(unsigned long interval)
pthread_create(&thr, NULL, burn_cpu_wakeups, (void *)interval);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
stop_measurement = 1;
sleep(1);
}
@@ -292,7 +292,7 @@ static void usb_calibration(void)
printf(_(".... device %s \n"), usb_devices[i].c_str());
suspend_all_usb_devices();
write_sysfs(usb_devices[i], "on\n");
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
suspend_all_usb_devices();
sleep(3);
}
@@ -309,7 +309,7 @@ static void rfkill_calibration(void)
printf(_(".... device %s \n"), rfkill_devices[i].c_str());
rfkill_all_radios();
write_sysfs(rfkill_devices[i], "0\n");
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
rfkill_all_radios();
sleep(3);
}
@@ -317,7 +317,7 @@ static void rfkill_calibration(void)
printf(_(".... device %s \n"), rfkill_devices[i].c_str());
unrfkill_all_radios();
write_sysfs(rfkill_devices[i], "1\n");
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
unrfkill_all_radios();
sleep(3);
}
@@ -333,29 +333,29 @@ static void backlight_calibration(void)
char str[4096];
printf(_(".... device %s \n"), backlight_devices[i].c_str());
lower_backlight();
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
sprintf(str, "%i\n", blmax / 4);
write_sysfs(backlight_devices[i], str);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
sprintf(str, "%i\n", blmax / 2);
write_sysfs(backlight_devices[i], str);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
sprintf(str, "%i\n", 3 * blmax / 4 );
write_sysfs(backlight_devices[i], str);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
sprintf(str, "%i\n", blmax);
write_sysfs(backlight_devices[i], str);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
lower_backlight();
sleep(1);
}
printf(_("Calibrating idle\n"));
if(!system("DISPLAY=:0 /usr/bin/xset dpms force off"))
printf("System is not available\n");
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
if(!system("DISPLAY=:0 /usr/bin/xset dpms force on"))
printf("System is not available\n");
}
@@ -365,7 +365,7 @@ static void idle_calibration(void)
printf(_("Calibrating idle\n"));
if(!system("DISPLAY=:0 /usr/bin/xset dpms force off"))
printf("System is not available\n");
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
if(!system("DISPLAY=:0 /usr/bin/xset dpms force on"))
printf("System is not available\n");
}
@@ -382,7 +382,7 @@ static void disk_calibration(void)
stop_measurement = 0;
pthread_create(&thr, NULL, burn_disk, NULL);
- one_measurement(15, NULL);
+ one_measurement(15, 15, NULL);
stop_measurement = 1;
sleep(1);
diff --git a/src/calibrate/calibrate.h b/src/calibrate/calibrate.h
index c279ae2..de71938 100644
--- a/src/calibrate/calibrate.h
+++ b/src/calibrate/calibrate.h
@@ -25,7 +25,7 @@
#ifndef __INCLUDE_GUARD_CALIBRATE_H
#define __INCLUDE_GUARD_CALIBRATE_H
-extern void one_measurement(int seconds, char *workload);
+extern void one_measurement(int seconds, int sample_interval, char *workload);
extern void calibrate(void);
diff --git a/src/devices/device.cpp b/src/devices/device.cpp
index 1757a55..2245b65 100644
--- a/src/devices/device.cpp
+++ b/src/devices/device.cpp
@@ -166,11 +166,13 @@ void report_devices(void)
- pw = global_joules_consumed();
+ pw = global_power();
if (pw > 0.0001) {
char buf[32];
wprintw(win, _("The battery reports a discharge rate of %sW\n"),
fmt_prefix(pw, buf));
+ wprintw(win, _("The power consumed was %sJ\n"),
+ fmt_prefix(global_joules(), buf));
}
if (show_power) {
@@ -248,13 +250,18 @@ void show_report_devices(void)
/* Device Summary */
int summary_size=2;
string *summary = new string[summary_size];
- pw = global_joules_consumed();
+ pw = global_power();
char buf[32];
if (pw > 0.0001) {
summary[0]= __("The battery reports a discharge rate of: ");
summary[1]=string(fmt_prefix(pw, buf));
summary[1].append(" W");
report.add_summary_list(summary, summary_size);
+
+ summary[0]= __("The power consumed was : ");
+ summary[1]=string(fmt_prefix(global_joules(), buf));
+ summary[1].append(" J");
+ report.add_summary_list(summary, summary_size);
}
if (show_power) {
diff --git a/src/main.cpp b/src/main.cpp
index f700208..991dd9a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -89,6 +89,7 @@ static const struct option long_options[] =
{"html", optional_argument, NULL, 'r'},
{"iteration", optional_argument, NULL, 'i'},
{"quiet", no_argument, NULL, 'q'},
+ {"sample", optional_argument, NULL, 's'},
{"time", optional_argument, NULL, 't'},
{"workload", optional_argument, NULL, 'w'},
{"version", no_argument, NULL, 'V'},
@@ -126,6 +127,7 @@ static void print_usage()
printf(" -r, --html%s\t %s\n", _("[=filename]"), _("generate a html report"));
printf(" -i, --iteration%s\n", _("[=iterations] number of times to run each test"));
printf(" -q, --quiet\t\t %s\n", _("suppress stderr output"));
+ printf(" -s, --sample%s\t %s\n", _("[=seconds]"), _("interval for power consumption measurement"));
printf(" -t, --time%s\t %s\n", _("[=seconds]"), _("generate a report for 'x' seconds"));
printf(" -w, --workload%s %s\n", _("[=workload]"), _("file to execute for workload"));
printf(" -V, --version\t\t %s\n", _("print version information"));
@@ -197,8 +199,20 @@ static void do_sleep(int seconds)
} while (1);
}
+extern "C" {
+ static volatile bool end_thread;
+ void* measure_background_thread(void *arg)
+ {
+ int sleep_time = *((int *) arg);
+ while (!end_thread) {
+ do_sleep(sleep_time);
+ global_sample_power();
+ }
+ return 0;
+ }
+}
-void one_measurement(int seconds, char *workload)
+void one_measurement(int seconds, int sample_interval, char *workload)
{
create_all_usb_devices();
start_power_measurement();
@@ -208,10 +222,27 @@ void one_measurement(int seconds, char *workload)
start_cpu_measurement();
if (workload && workload[0]) {
+ pthread_t thread = 0UL;
+ end_thread = false;
+ if (pthread_create(&thread, NULL, measure_background_thread, &sample_interval))
+ fprintf(stderr, "ERROR: workload measurement thread creation failed\n");
+
if (system(workload))
fprintf(stderr, _("Unknown issue running workload!\n"));
+
+ if (thread)
+ {
+ end_thread = true;
+ pthread_join( thread, NULL);
+ }
+ global_sample_power();
} else {
- do_sleep(seconds);
+ while (seconds > 0)
+ {
+ do_sleep(sample_interval > seconds ? seconds : sample_interval);
+ seconds -= sample_interval;
+ global_sample_power();
+ }
}
end_cpu_measurement();
end_process_measurement();
@@ -237,7 +268,7 @@ void one_measurement(int seconds, char *workload)
end_process_data();
- global_joules_consumed();
+ global_power();
compute_bundle();
show_report_devices();
@@ -258,13 +289,13 @@ void out_of_memory()
abort();
}
-void make_report(int time, char *workload, int iterations, char *file)
+void make_report(int time, char *workload, int iterations, int sample_interval, char *file)
{
/* one to warm up everything */
fprintf(stderr, _("Preparing to take measurements\n"));
utf_ok = 0;
- one_measurement(1, NULL);
+ one_measurement(1, sample_interval, NULL);
if (!workload[0])
fprintf(stderr, _("Taking %d measurement(s) for a duration of %d second(s) each.\n"),iterations,time);
@@ -274,7 +305,7 @@ void make_report(int time, char *workload, int iterations, char *file)
init_report_output(file, iterations);
initialize_tuning();
/* and then the real measurement */
- one_measurement(time, workload);
+ one_measurement(time, sample_interval, workload);
report_show_tunables();
finish_report_output();
clear_tuning();
@@ -398,7 +429,7 @@ int main(int argc, char **argv)
int c;
char filename[PATH_MAX];
char workload[PATH_MAX] = {0};
- int iterations = 1, auto_tune = 0;
+ int iterations = 1, auto_tune = 0, sample_interval = 5;
set_new_handler(out_of_memory);
@@ -456,6 +487,9 @@ int main(int argc, char **argv)
if (freopen("/dev/null", "a", stderr))
fprintf(stderr, _("Quiet mode failed!\n"));
break;
+ case 's':
+ sample_interval = (optarg ? atoi(optarg) : 5);
+ break;
case 't':
time_out = (optarg ? atoi(optarg) : 20);
break;
@@ -480,7 +514,7 @@ int main(int argc, char **argv)
powertop_init(auto_tune);
if (reporttype != REPORT_OFF)
- make_report(time_out, workload, iterations, filename);
+ make_report(time_out, workload, iterations, sample_interval, filename);
if (debug_learning)
printf("Learning debugging enabled\n");
@@ -501,7 +535,7 @@ int main(int argc, char **argv)
initialize_devfreq();
initialize_tuning();
/* first one is short to not let the user wait too long */
- one_measurement(1, NULL);
+ one_measurement(1, sample_interval, NULL);
if (!auto_tune) {
tuning_update_display();
@@ -513,7 +547,7 @@ int main(int argc, char **argv)
while (!leave_powertop) {
if (!auto_tune)
show_cur_tab();
- one_measurement(time_out, NULL);
+ one_measurement(time_out, sample_interval, NULL);
learn_parameters(15, 0);
}
if (!auto_tune)
diff --git a/src/measurement/acpi.cpp b/src/measurement/acpi.cpp
index 2c9815d..ede2782 100644
--- a/src/measurement/acpi.cpp
+++ b/src/measurement/acpi.cpp
@@ -207,7 +207,7 @@ void acpi_power_meter::start_measurement(void)
}
-double acpi_power_meter::joules_consumed(void)
+double acpi_power_meter::power(void)
{
return rate;
}
diff --git a/src/measurement/acpi.h b/src/measurement/acpi.h
index 315fddf..25bbe04 100644
--- a/src/measurement/acpi.h
+++ b/src/measurement/acpi.h
@@ -39,7 +39,7 @@ public:
virtual void start_measurement(void);
virtual void end_measurement(void);
- virtual double joules_consumed(void);
+ virtual double power(void);
virtual double dev_capacity(void) { return capacity; };
};
diff --git a/src/measurement/extech.cpp b/src/measurement/extech.cpp
index e014a5d..0849907 100644
--- a/src/measurement/extech.cpp
+++ b/src/measurement/extech.cpp
@@ -347,7 +347,7 @@ void extech_power_meter::start_measurement(void)
}
-double extech_power_meter::joules_consumed(void)
+double extech_power_meter::power(void)
{
return rate;
}
diff --git a/src/measurement/extech.h b/src/measurement/extech.h
index 5f4c338..b7b330a 100644
--- a/src/measurement/extech.h
+++ b/src/measurement/extech.h
@@ -44,7 +44,7 @@ public:
virtual void end_measurement(void);
virtual void sample(void);
- virtual double joules_consumed(void);
+ virtual double power(void);
virtual double dev_capacity(void) { return 0.0; };
};
diff --git a/src/measurement/measurement.cpp b/src/measurement/measurement.cpp
index 1c8e4da..caee24e 100644
--- a/src/measurement/measurement.cpp
+++ b/src/measurement/measurement.cpp
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <fstream>
#include <unistd.h>
+#include <time.h>
double min_power = 50000.0;
@@ -49,18 +50,22 @@ void power_meter::end_measurement(void)
}
-double power_meter::joules_consumed(void)
+double power_meter::power(void)
{
return 0.0;
}
vector<class power_meter *> power_meters;
+static struct timespec tlast;
+
void start_power_measurement(void)
{
unsigned int i;
+ clock_gettime(CLOCK_REALTIME, &tlast);
for (i = 0; i < power_meters.size(); i++)
power_meters[i]->start_measurement();
+ all_results.joules = 0.0;
}
void end_power_measurement(void)
{
@@ -69,7 +74,7 @@ void end_power_measurement(void)
power_meters[i]->end_measurement();
}
-double global_joules_consumed(void)
+double global_power(void)
{
bool global_discharging = false;
double total = 0.0;
@@ -77,8 +82,9 @@ double global_joules_consumed(void)
for (i = 0; i < power_meters.size(); i++) {
global_discharging |= power_meters[i]->is_discharging();
- total += power_meters[i]->joules_consumed();
+ total += power_meters[i]->power();
}
+
/* report global time left if at least one battery is discharging */
if (!global_discharging)
return 0.0;
@@ -89,6 +95,23 @@ double global_joules_consumed(void)
return total;
}
+void global_sample_power(void)
+{
+ struct timespec tnow;
+
+ clock_gettime(CLOCK_REALTIME, &tnow);
+ /* power * time = joules */
+ all_results.joules += global_power() * \
+ ( ((double)tnow.tv_sec + 1.0e-9*tnow.tv_nsec) - \
+ ((double)tlast.tv_sec + 1.0e-9*tlast.tv_nsec));
+ tlast = tnow;
+}
+
+double global_joules(void)
+{
+ return all_results.joules;
+}
+
double global_time_left(void)
{
bool global_discharging = false;
@@ -98,7 +121,7 @@ double global_time_left(void)
for (i = 0; i < power_meters.size(); i++) {
global_discharging |= power_meters[i]->is_discharging();
total_capacity += power_meters[i]->dev_capacity();
- total_rate += power_meters[i]->joules_consumed();
+ total_rate += power_meters[i]->power();
}
/* report global time left if at least one battery is discharging */
if (!global_discharging)
diff --git a/src/measurement/measurement.h b/src/measurement/measurement.h
index 83ffc34..df0ceca 100644
--- a/src/measurement/measurement.h
+++ b/src/measurement/measurement.h
@@ -36,7 +36,7 @@ public:
virtual void start_measurement(void);
virtual void end_measurement(void);
- virtual double joules_consumed(void);
+ virtual double power(void);
virtual double dev_capacity(void)
{
@@ -58,7 +58,9 @@ extern vector<class power_meter *> power_meters;
extern void start_power_measurement(void);
extern void end_power_measurement(void);
-extern double global_joules_consumed(void);
+extern double global_power(void);
+extern void global_sample_power(void);
+extern double global_joules(void);
extern double global_time_left(void);
extern void detect_power_meters(void);
diff --git a/src/measurement/opal-sensors.cpp b/src/measurement/opal-sensors.cpp
index 7316d1f..a70ec56 100644
--- a/src/measurement/opal-sensors.cpp
+++ b/src/measurement/opal-sensors.cpp
@@ -34,7 +34,7 @@ opal_sensors_power_meter::opal_sensors_power_meter(const char *power_supply_name
strncpy(name, power_supply_name, sizeof(name));
}
-double opal_sensors_power_meter::joules_consumed(void)
+double opal_sensors_power_meter::power(void)
{
bool ok;
int value;
diff --git a/src/measurement/opal-sensors.h b/src/measurement/opal-sensors.h
index 8347733..7962091 100644
--- a/src/measurement/opal-sensors.h
+++ b/src/measurement/opal-sensors.h
@@ -35,7 +35,7 @@ public:
virtual void start_measurement(void) {};
virtual void end_measurement(void) {};
- virtual double joules_consumed(void);
+ virtual double power(void);
virtual double dev_capacity(void) { return 0.0; }
};
diff --git a/src/measurement/sysfs.h b/src/measurement/sysfs.h
index b7efa3d..5b440f5 100644
--- a/src/measurement/sysfs.h
+++ b/src/measurement/sysfs.h
@@ -48,7 +48,7 @@ public:
virtual void start_measurement(void);
virtual void end_measurement(void);
- virtual double joules_consumed(void) { return rate; }
+ virtual double power(void) { return rate; }
virtual double dev_capacity(void) { return capacity; }
};
diff --git a/src/parameters/parameters.cpp b/src/parameters/parameters.cpp
index 3bd5c05..38e1752 100644
--- a/src/parameters/parameters.cpp
+++ b/src/parameters/parameters.cpp
@@ -327,7 +327,7 @@ void store_results(double duration)
{
if (duration < 5)
return;
- global_joules_consumed();
+ global_power();
if (all_results.power > 0.01) {
unsigned int overflow_index;
overflow_index = 50 + (rand() % MAX_KEEP);
diff --git a/src/parameters/parameters.h b/src/parameters/parameters.h
index 72f8d32..1781a0e 100644
--- a/src/parameters/parameters.h
+++ b/src/parameters/parameters.h
@@ -66,6 +66,7 @@ extern void set_parameter_value(const char *name, double value, struct parameter
struct result_bundle
{
+ double joules;
double power;
vector <double> utilization; /* device name, device utilization %age */
};
diff --git a/src/process/do_process.cpp b/src/process/do_process.cpp
index 391cb7f..812572c 100644
--- a/src/process/do_process.cpp
+++ b/src/process/do_process.cpp
@@ -787,6 +787,7 @@ void process_update_display(void)
unsigned int i;
WINDOW *win;
double pw;
+ double joules;
int tl;
int tlt;
int tlr;
@@ -816,10 +817,11 @@ void process_update_display(void)
}
wprintw(win, _("Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n\n"),
- all_parameters.guessed_power, global_joules_consumed(), sum);
+ all_parameters.guessed_power, global_power(), sum);
#endif
- pw = global_joules_consumed();
+ pw = global_power();
+ joules = global_joules();
tl = global_time_left() / 60;
tlt = (tl /60);
tlr = tl % 60;
@@ -828,6 +830,8 @@ void process_update_display(void)
char buf[32];
wprintw(win, _("The battery reports a discharge rate of %sW\n"),
fmt_prefix(pw, buf));
+ wprintw(win, _("The power consumed was %sJ\n"),
+ fmt_prefix(joules, buf));
need_linebreak = 1;
}
if (tl > 0 && pw > 0.0001) {