diff --git a/checkin_notes b/checkin_notes index 8cafbd067f..71a14cf29b 100755 --- a/checkin_notes +++ b/checkin_notes @@ -8065,3 +8065,14 @@ David 19 June 2005 client/ cs_scheduler.C + +David 19 June 2005 + - work-fetch policy: + if fetching work would cause deadlines to be missed + (based on round-robin simulation) then don't fetch work + - factor simulations of EDF and round-robin + into separate functions + + client/ + client_state.h + cs_scheduler.C diff --git a/client/client_state.h b/client/client_state.h index e6184dd11c..1fd73ed814 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -305,6 +305,8 @@ private: bool should_get_work(); bool no_work_for_a_cpu(); int proj_min_results(PROJECT*, double); + bool round_robin_misses_deadline(double, double); + bool edf_misses_deadline(double); void set_scheduler_modes(); // --------------- cs_statefile.C: diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 2fd0b3e208..b21c569219 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -998,34 +998,18 @@ bool CLIENT_STATE::no_work_for_a_cpu() { return ncpus > count; } -// Decide on modes for work-fetch and CPU sched policies. -// Namely, set the variables -// - work_fetch_no_new_work -// - cpu_earliest_deadline_first -// and print a message if we're changing their value +// simulate weighted round-robin scheduling, +// and see if any result misses its deadline // -void CLIENT_STATE::set_scheduler_modes() { - std::map results_by_deadline; - RESULT* rp; - unsigned int i, j; - int k; - bool should_not_fetch_work = false; - bool use_earliest_deadline_first = false; +bool CLIENT_STATE::round_robin_misses_deadline(double per_cpu_proc_rate, double rrs) { + bool round_robin_misses_deadline = false; std::vector booked_to; -#if 0 - double frac_booked = 0; - std::map::iterator it; -#endif - double total_proc_rate = avg_proc_rate(); - double per_cpu_proc_rate = total_proc_rate/ncpus; + int k; + unsigned int i, j; + RESULT* rp; SCOPE_MSG_LOG scope_messages(log_messages, CLIENT_MSG_LOG::DEBUG_SCHED_CPU); - // simulate weighted round-robin scheduling, - // and see if any result misses its deadline - // - bool round_robin_misses_deadline = false; - double rrs = runnable_resource_share(); for (k=0; kname, booked_to[ifirst], rp->report_deadline ); if (booked_to[ifirst] > rp->report_deadline) { - round_robin_misses_deadline = true; - break; + return true; } } - if (round_robin_misses_deadline) break; } - if (round_robin_misses_deadline) { + return false; +} + +#if 0 +// Simulate what will happen if we do EDF schedule starting now. +// Go through non-done results in EDF order, +// keeping track in "booked_to" of how long each CPU is occupied +// +bool CLIENT_STATE::edf_misses_deadline(double per_cpu_proc_rate) { + std::map::iterator it; + std::map results_by_deadline; + std::vector booked_to; + unsigned int i; + int j; + RESULT* rp; + + for (j=0; jcomputing_done()) continue; + if (rp->project->non_cpu_intensive) continue; + results_by_deadline[rp->report_deadline] = rp; + } + + for ( + it = results_by_deadline.begin(); + it != results_by_deadline.end(); + it++ + ) { + rp = (*it).second; + + // find the CPU that will be free first + // + double lowest_book = booked_to[0]; + int lowest_booked_cpu = 0; + for (j=1; jestimated_cpu_time_remaining() + /(per_cpu_proc_rate*CPU_PESSIMISM_FACTOR); + if (booked_to[lowest_booked_cpu] > rp->report_deadline) { + return true; + } + } + return false; +} +#endif + +// Decide on modes for work-fetch and CPU sched policies. +// Namely, set the variables +// - work_fetch_no_new_work +// - cpu_earliest_deadline_first +// and print a message if we're changing their value +// +void CLIENT_STATE::set_scheduler_modes() { + RESULT* rp; + unsigned int i; + bool should_not_fetch_work = false; + bool use_earliest_deadline_first = false; + 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); + + double rrs = runnable_resource_share(); + if (round_robin_misses_deadline(per_cpu_proc_rate, rrs)) { + // if round robin would miss a deadline, use EDF + // use_earliest_deadline_first = true; if (!no_work_for_a_cpu()) { should_not_fetch_work = true; } + } else { + // if fetching more work would cause round-robin to + // miss a deadline, don't fetch more work + // + PROJECT* p = next_project_need_work(); + if (p && !p->runnable()) { + rrs += p->resource_share; + if (round_robin_misses_deadline(per_cpu_proc_rate, rrs)) { + should_not_fetch_work = true; + } + } } for (i=0; ireport_deadline] = rp; -#endif } #if 0 - 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( - "set_scheduler_modes(): Computer is overcommitted\n" - ); - break; - } + if (edf_misses_deadline(per_cpu_proc_rate)) { + should_not_fetch_work = true; + use_earliest_deadline_first = true; + scope_messages.printf( + "set_scheduler_modes(): Computer is overcommitted\n" + ); } #endif