diff --git a/checkin_notes b/checkin_notes index 58f534b984..7491eb9c69 100755 --- a/checkin_notes +++ b/checkin_notes @@ -7886,3 +7886,21 @@ David 15 June 2005 forum.inc lib/ app_ipc.C,h + +David 15 June 2005 + Scheduler changes: + + - renamed set_cpu_scheduler_modes() to set_scheduler_modes() + - in set_scheduler_modes(), moved result checks that + don't involve EDF simulation out of the loop that does EDF simulation. + - in set_scheduler_modes(), change logic so that booked_to + is in units of wall time, not CPU time. + Makes things clearer. + - removed the frac_booked logic from set_scheduler_modes(). + I don't think this is correct. + e.g. result A has deadline 1, CPU 1; result B has deadline 2, CPU 1. + Then frac_booked would be 1.5, but we can meet both deadlines + - renamed MAX_CPU_LOAD_FACTOR to CPU_PESSIMISM_FACTOR + + client/ + cs_scheduler.C diff --git a/client/client_state.h b/client/client_state.h index 3a1ae5b34e..d25b174acd 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -307,7 +307,7 @@ private: bool should_get_work(); bool no_work_for_a_cpu(); int proj_min_results(PROJECT*, double); - void set_cpu_scheduler_modes(); + void set_scheduler_modes(); // --------------- cs_statefile.C: public: diff --git a/client/cs_apps.C b/client/cs_apps.C index a37faf1035..4cc87b3273 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -569,7 +569,7 @@ bool CLIENT_STATE::schedule_cpus() { results[i]->already_selected = false; } - set_cpu_scheduler_modes(); + set_scheduler_modes(); adjust_debts(); // mark active tasks as preempted diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 3a37768585..611c37163c 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -66,9 +66,10 @@ const int SECONDS_BEFORE_REPORTING_MIN_RPC_TIME_AGAIN = 60*60; // #define REPORT_DEADLINE_CUSHION SECONDS_PER_DAY -// try to maintain no more than this load factor on the CPU. +// assume actual CPU utilization will be this multiple +// of what we've actually measured recently // -#define MAX_CPU_LOAD_FACTOR 0.8 +#define CPU_PESSIMISM_FACTOR 0.8 // how many CPUs should this project occupy on average, // based on its resource share relative to a given set @@ -967,7 +968,7 @@ bool CLIENT_STATE::should_get_work() { // let it process for a while to get out of the CPU overload state. // if (!work_fetch_no_new_work) { - set_cpu_scheduler_modes(); + set_scheduler_modes(); } bool ret = !work_fetch_no_new_work; @@ -994,64 +995,27 @@ bool CLIENT_STATE::no_work_for_a_cpu() { // - cpu_earliest_deadline_first // and print a message if we're changing their value // -void CLIENT_STATE::set_cpu_scheduler_modes() { +void CLIENT_STATE::set_scheduler_modes() { std::map results_by_deadline; - std::set projects_with_work; RESULT* rp; - int i; + unsigned int i; bool should_not_fetch_work = false; bool use_earliest_deadline_first = false; double frac_booked = 0; std::vector booked_to; std::map::iterator it; - double apr = avg_proc_rate(); + double total_proc_rate = avg_proc_rate(); + double per_cpu_proc_rate = total_proc_rate/ncpus; SCOPE_MSG_LOG scope_messages(log_messages, CLIENT_MSG_LOG::DEBUG_SCHED_CPU); std::vector::iterator it_u; - for (it_u = results.begin(); it_u != results.end(); ++it_u) { - rp = *it_u; + for (i=0; icomputing_done()) continue; if (rp->project->non_cpu_intensive) continue; - results_by_deadline[rp->report_deadline] = rp; - projects_with_work.insert(rp->project); - } - - for (i=0; iproject->non_cpu_intensive) continue; - if (rp->computing_done()) continue; - - double lowest_book = booked_to[0]; - int lowest_booked_cpu = 0; - for (i=1; iestimated_cpu_time_remaining(); - - // Are the deadlines too tight to meet reliably? - // - if (booked_to[lowest_booked_cpu] - gstate.now > (rp->report_deadline - gstate.now) * MAX_CPU_LOAD_FACTOR * (apr / ncpus)) { - should_not_fetch_work = true; - use_earliest_deadline_first = true; - scope_messages.printf( - "CLIENT_STATE::compute_work_requests(): Computer is overcommitted\n" - ); - } // Is the nearest deadline within a day? // if (rp->report_deadline - gstate.now < 60 * 60 * 24) { @@ -1070,14 +1034,47 @@ void CLIENT_STATE::set_cpu_scheduler_modes() { ); } - frac_booked += rp->estimated_cpu_time_remaining() / (rp->report_deadline - gstate.now); + results_by_deadline[rp->report_deadline] = rp; } - if (frac_booked > MAX_CPU_LOAD_FACTOR * apr) { - should_not_fetch_work = true; - scope_messages.printf( - "CLIENT_STATE::compute_work_requests(): Nearly overcommitted.\n" - ); + for (i=0; iestimated_cpu_time_remaining() + /(per_cpu_proc_rate*CPU_PESSIMISM_FACTOR); + + // Are the deadlines too tight to meet reliably? + // + if (booked_to[lowest_booked_cpu] > rp->report_deadline) { + should_not_fetch_work = true; + use_earliest_deadline_first = true; + scope_messages.printf( + "CLIENT_STATE::compute_work_requests(): Computer is overcommitted\n" + ); + break; + } } // display only when the policy changes to avoid once per second