static void weed_empties(struct parameter_bundle *best_so_far) { double best_score; unsigned int i; best_score = best_so_far->score; for (i = 0; i < best_so_far->parameters.size(); i++) { double orgvalue; orgvalue = best_so_far->parameters[i]; best_so_far->parameters[i] = 0.0; calculate_params(best_so_far); if (best_so_far->score > best_score) { best_so_far->parameters[i] = orgvalue; } else { best_score = best_so_far->score; } } calculate_params(best_so_far); }
/* leaks like a sieve */ void learn_parameters(int iterations, int do_base_power) { struct parameter_bundle *best_so_far; double best_score = 10000000000000000.0; int retry = iterations; int prevparam = -1; int locked = 0; static unsigned int bpi = 0; unsigned int i; time_t start; if (global_fixed_parameters) return; /* don't start fitting anything until we have at least 1 more measurement than we have parameters */ if (past_results.size() <= all_parameters.parameters.size()) return; // if (past_results.size() == previous_measurements) // return; precompute_valid(); previous_measurements = past_results.size(); double delta = 0.50; best_so_far = &all_parameters; if (!bpi) bpi = get_param_index("base power"); calculate_params(best_so_far); best_score = best_so_far->score; delta = 0.001 / pow(0.8, iterations / 2.0); if (iterations < 25) delta = 0.001 / pow(0.5, iterations / 2.0); if (delta > 0.2) delta = 0.2; if (1.0 * best_score / past_results.size() < 4 && delta > 0.05) delta = 0.05; if (debug_learning) printf("Delta starts at %5.3f\n", delta); if (best_so_far->parameters[bpi] > min_power * 0.9) best_so_far->parameters[bpi] = min_power * 0.9; /* We want to give up a little of base power, to give other parameters room to change; base power is the end post for everything after all */ if (do_base_power && !debug_learning) best_so_far->parameters[bpi] = best_so_far->parameters[bpi] * 0.9998; start = time(NULL); while (retry--) { int changed = 0; int bestparam; double newvalue = 0; double orgscore; double weight; bestparam = -1; if (time(NULL) - start > 1 && !debug_learning) retry = 0; calculate_params(best_so_far); orgscore = best_score = best_so_far->score; for (i = 1; i < best_so_far->parameters.size(); i++) { double value, orgvalue; weight = delta * best_so_far->weights[i]; orgvalue = value = best_so_far->parameters[i]; if (value <= 0.001) { value = 0.1; } else value = value * (1 + weight); if (i == bpi && value > min_power) value = min_power; if (i == bpi && orgvalue > min_power) orgvalue = min_power; if (value > 5000) value = 5000; // printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), best_so_far->parameters[param], value); best_so_far->parameters[i] = 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 = i; changed++; } value = orgvalue * 1 / (1 + weight); 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", param.c_str(), orgvalue, value); if (orgvalue != value) { best_so_far->parameters[i] = 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 = i; changed++; } } best_so_far->parameters[i] = orgvalue; } if (!changed) { double mult; if (!locked) { mult = 0.8; if (iterations < 25) mult = 0.5; delta = delta * mult; } locked = 0; prevparam = -1; } else { if (debug_learning) { printf("Retry is %i \n", retry); printf("delta is %5.4f\n", delta); printf("Best parameter is %i \n", bestparam); 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 && !locked) break; if (retry % 50 == 49) weed_empties(best_so_far); } /* now we weed out all parameters that don't have value */ if (iterations > 50) weed_empties(best_so_far); if (debug_learning) printf("Final score %4.2f (%i points)\n", best_so_far->score / past_results.size(), (int)past_results.size()); // dump_parameter_bundle(best_so_far); // dump_past_results(); }
void process_update_display(void) { #ifndef DISABLE_NCURSES unsigned int i; WINDOW *win; double pw; int tl; int tlt; int tlr; int show_power; int need_linebreak = 0; sort(all_power.begin(), all_power.end(), power_cpu_sort); show_power = global_power_valid(); win = get_ncurses_win("Overview"); if (!win) return; wclear(win); wmove(win, 1,0); #if 0 double sum; calculate_params(); sum = 0.0; sum += get_parameter_value("base power"); for (i = 0; i < all_power.size(); i++) { sum += all_power[i]->Witts(); } wprintw(win, _("Estimated power: %5.1f Measured power: %5.1f Sum: %5.1f\n\n"), all_parameters.guessed_power, global_joules_consumed(), sum); #endif pw = global_joules_consumed(); tl = global_time_left() / 60; tlt = (tl /60); tlr = tl % 60; if (pw > 0.0001) { char buf[32]; wprintw(win, _("The battery reports a discharge rate of %sW\n"), fmt_prefix(pw, buf)); need_linebreak = 1; } if (tl > 0 && pw > 0.0001) { wprintw(win, _("The estimated remaining time is %i hours, %i minutes\n"), tlt, tlr); need_linebreak = 1; } if (need_linebreak) wprintw(win, "\n"); wprintw(win, "%s: %3.1f %s, %3.1f %s, %3.1f %s %3.1f%% %s\n\n",_("Summary"), total_wakeups(), _("wakeups/second"), total_gpu_ops(), _("GPU ops/seconds"), total_disk_hits(), _("VFS ops/sec and"), total_cpu_time()*100, _("CPU use")); if (show_power) wprintw(win, "%s %s %s %s %s\n", _("Power est."), _("Usage"), _("Events/s"), _("Category"), _("Description")); else wprintw(win, " %s %s %s %s\n", _("Usage"), _("Events/s"), _("Category"), _("Description")); for (i = 0; i < all_power.size(); i++) { char power[16]; char name[20]; char usage[20]; char events[20]; char descr[128]; format_watts(all_power[i]->Witts(), power, 10); if (!show_power) strcpy(power, " "); sprintf(name, "%s", all_power[i]->type()); while (mbstowcs(NULL,name,0) < 14) strcat(name, " "); if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && all_power[i]->Witts() == 0) break; usage[0] = 0; if (all_power[i]->usage_units()) { if (all_power[i]->usage() < 1000) sprintf(usage, "%5.1f%s", all_power[i]->usage(), all_power[i]->usage_units()); else sprintf(usage, "%5i%s", (int)all_power[i]->usage(), all_power[i]->usage_units()); } while (mbstowcs(NULL,usage,0) < 14) strcat(usage, " "); sprintf(events, "%5.1f", all_power[i]->events()); if (!all_power[i]->show_events()) events[0] = 0; else if (all_power[i]->events() <= 0.3) sprintf(events, "%5.2f", all_power[i]->events()); while (strlen(events) < 12) strcat(events, " "); wprintw(win, "%s %s %s %s %s\n", power, usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); } #endif // DISABLE_NCURSES }