API/client: let apps say that fraction done is precise

Currently the duration estimate for a task is a combination of
- a static estimate, based on wu.rsc_fpops_est and the estimated FLOPS
- a dynamic estimate, based on fraction done (FD) and elapsed time
The weighting of the dynamic estimate is FD^2;
the assumption is that fraction done is imprecise and improves
toward the end of a task.

This isn't ideal for apps that can supply accurate FD.

Solution: add a new API function
boinc_fraction_done_exact().
This notifies the client that the FD is accurate,
and that it should use only the dynamic estimate.
(New clients will do this; old clients will use the FD as the currently do).
This commit is contained in:
David Anderson 2014-05-02 23:11:34 -07:00
parent 6b1a0731f1
commit 77c4dd7b32
5 changed files with 26 additions and 2 deletions

View File

@ -127,6 +127,7 @@ APP_CLIENT_SHM* app_client_shm = 0;
static volatile int time_until_checkpoint;
// time until enable checkpoint
static volatile double fraction_done;
static volatile bool fd_exact = false;
static volatile double last_checkpoint_cpu_time;
static volatile bool ready_to_checkpoint = false;
static volatile int in_critical_section = 0;
@ -383,6 +384,9 @@ static bool update_app_progress(double cpu_t, double cp_cpu_t) {
sprintf(buf, "<fraction_done>%e</fraction_done>\n", fdone);
strlcat(msg_buf, buf, sizeof(msg_buf));
}
if (fd_exact) {
strlcat(msg_buf, "<fd_exact/>\n", sizeof(msg_buf));
}
if (bytes_sent) {
sprintf(buf, "<bytes_sent>%f</bytes_sent>\n", bytes_sent);
strlcat(msg_buf, buf, sizeof(msg_buf));
@ -849,6 +853,8 @@ int boinc_parse_init_data_file() {
return 0;
}
// used by wrappers
//
int boinc_report_app_status_aux(
double cpu_time,
double checkpoint_cpu_time,
@ -1429,6 +1435,12 @@ int boinc_fraction_done(double x) {
return 0;
}
int boinc_fraction_done_exact(double x) {
fraction_done = x;
fd_exact = true;
return 0;
}
int boinc_receive_trickle_down(char* buf, int len) {
std::string filename;
char path[MAXPATHLEN];

View File

@ -92,6 +92,7 @@ extern int boinc_send_trickle_up(char* variety, char* text);
extern int boinc_set_min_checkpoint_period(int);
extern int boinc_checkpoint_completed(void);
extern int boinc_fraction_done(double);
extern int boinc_fraction_done_exact(double);
extern int boinc_suspend_other_activities(void);
extern int boinc_resume_other_activities(void);
extern int boinc_report_app_status(

View File

@ -108,6 +108,8 @@ struct ACTIVE_TASK {
// will be zero if the app doesn't use this call
double fraction_done_elapsed_time;
// elapsed time when fraction done was last reported
bool fraction_done_exact;
// true if app thinks fraction done is accurate
int scheduler_state;
int next_scheduler_state; // temp
int signal;

View File

@ -1349,6 +1349,7 @@ bool ACTIVE_TASK::get_app_status_msg() {
bytes_received_episode = dtemp;
}
parse_int(msg_buf, "<want_network>", want_network);
parse_bool(msg_buf, "fd_exact", fraction_done_exact);
if (parse_int(msg_buf, "<other_pid>", other_pid)) {
// for now, we handle only one of these
other_pids.clear();

View File

@ -1052,10 +1052,18 @@ void CLIENT_STATE::compute_nuploading_results() {
double ACTIVE_TASK::est_dur() {
if (fraction_done >= 1) return elapsed_time;
double wu_est = result->estimated_runtime();
if (fraction_done <= 0) return wu_est;
if (wu_est < elapsed_time) wu_est = elapsed_time;
if (fraction_done <= 0) return wu_est;
double frac_est = fraction_done_elapsed_time / fraction_done;
double fd_weight = fraction_done * fraction_done;
// if app says fraction done is accurate, just use it
//
if (fraction_done_exact) return frac_est;
// weighting of dynamic estimate is the fraction done
// i.e. when fraction done is 0.5, weighting is 50/50
//
double fd_weight = fraction_done;
double wu_weight = 1 - fd_weight;
double x = fd_weight*frac_est + wu_weight*wu_est;
#if 0