From 18d6f5e708c2cb51b60e5b568016998bef1743d5 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 23 May 2008 22:03:27 +0000 Subject: [PATCH] - client: handle coprocs in RR simulation. Not tested. TODO: handle multithread apps in RR simulation; should be easy now. svn path=/trunk/boinc/; revision=15288 --- checkin_notes | 10 ++++++ client/client_types.h | 4 +-- client/cpu_sched.C | 73 ++++++++++++++++++++++++++++--------------- lib/coproc.h | 8 +++++ 4 files changed, 68 insertions(+), 27 deletions(-) diff --git a/checkin_notes b/checkin_notes index 7fcef281e3..d98d0c3fb3 100644 --- a/checkin_notes +++ b/checkin_notes @@ -4297,3 +4297,13 @@ David May 23 2008 cpu_sched.C lib/ coproc.h + +David May 23 2008 + - client: handle coprocs in RR simulation. Not tested. + TODO: handle multithread apps in RR simulation; should be easy now. + + client/ + client_types.h + cpu_sched.C + lib/ + coproc.h diff --git a/client/client_types.h b/client/client_types.h index 54dbd93949..b4018d4414 100644 --- a/client/client_types.h +++ b/client/client_types.h @@ -151,7 +151,7 @@ struct DAILY_STATS { }; bool operator < (const DAILY_STATS&, const DAILY_STATS&); -struct RR_SIM_STATUS { +struct RR_SIM_PROJECT_STATUS { std::vectoractive; // jobs currently running (in simulation) std::vectorpending; @@ -351,7 +351,7 @@ public: // a download is backed off bool some_result_suspended(); - RR_SIM_STATUS rr_sim_status; + RR_SIM_PROJECT_STATUS rr_sim_status; // temps used in CLIENT_STATE::rr_simulation(); void set_rrsim_proc_rate(double rrs); diff --git a/client/cpu_sched.C b/client/cpu_sched.C index d8d0a6ea6c..4902ab0192 100644 --- a/client/cpu_sched.C +++ b/client/cpu_sched.C @@ -1078,6 +1078,41 @@ void PROJECT::set_rrsim_proc_rate(double rrs) { } } +struct RR_SIM_STATUS { + vector active; + COPROCS coprocs; + + inline bool can_run(RESULT* rp) { + return coprocs.sufficient_coprocs(rp->avp->coprocs, log_flags.rr_simulation); + } + inline void activate(RESULT* rp) { + coprocs.reserve_coprocs(rp->avp->coprocs, log_flags.rr_simulation); + active.push_back(rp); + } + // remove *rpbest from active set, + // and adjust CPU time left for other results + // + inline void remove_active(RESULT* rpbest) { + coprocs.free_coprocs(rpbest->avp->coprocs, log_flags.rr_simulation); + vector::iterator it = active.begin(); + while (it != active.end()) { + RESULT* rp = *it; + if (rp == rpbest) { + it = active.erase(it); + } else { + rp->rrsim_cpu_left -= rp->project->rr_sim_status.proc_rate*rpbest->rrsim_finish_delay; + it++; + } + } + } + inline int nactive() { + return (int) active.size(); + } + ~RR_SIM_STATUS() { + coprocs.delete_coprocs(); + } +}; + // Do a simulation of the current workload // with weighted round-robin (WRR) scheduling. // Include jobs that are downloading. @@ -1107,11 +1142,11 @@ void CLIENT_STATE::rr_simulation() { double trs = total_resource_share(); PROJECT* p, *pbest; RESULT* rp, *rpbest; - vector active; + RR_SIM_STATUS sim_status; unsigned int i; double x; - vector::iterator it; + sim_status.coprocs.clone(coprocs); double ar = available_ram(); if (log_flags.rr_simulation) { @@ -1136,8 +1171,8 @@ void CLIENT_STATE::rr_simulation() { if (rp->project->non_cpu_intensive) continue; rp->rrsim_cpu_left = rp->estimated_cpu_time_remaining(false); p = rp->project; - if (p->rr_sim_status.can_run(rp, gstate.ncpus)) { - active.push_back(rp); + if (p->rr_sim_status.can_run(rp, gstate.ncpus) && sim_status.can_run(rp)) { + sim_status.activate(rp); p->rr_sim_status.activate(rp); } else { p->rr_sim_status.add_pending(rp); @@ -1170,13 +1205,13 @@ void CLIENT_STATE::rr_simulation() { // double sim_now = now; cpu_shortfall = 0; - while (active.size()) { + while (sim_status.nactive()) { // compute finish times and see which result finishes first // rpbest = NULL; - for (i=0; iproject; rp->rrsim_finish_delay = rp->rrsim_cpu_left/p->rr_sim_status.proc_rate; if (!rpbest || rp->rrsim_finish_delay < rpbest->rrsim_finish_delay) { @@ -1218,23 +1253,10 @@ void CLIENT_STATE::rr_simulation() { } } - int last_active_size = (int)active.size(); + int last_active_size = sim_status.nactive(); int last_proj_active_size = pbest->rr_sim_status.cpus_used(); - // remove *rpbest from active set, - // and adjust CPU time left for other results - // - it = active.begin(); - while (it != active.end()) { - rp = *it; - if (rp == rpbest) { - it = active.erase(it); - } else { - x = rp->project->rr_sim_status.proc_rate*rpbest->rrsim_finish_delay; - rp->rrsim_cpu_left -= x; - it++; - } - } + sim_status.remove_active(rpbest); pbest->rr_sim_status.remove_active(rpbest); @@ -1243,8 +1265,8 @@ void CLIENT_STATE::rr_simulation() { while (1) { rp = pbest->rr_sim_status.get_pending(); if (!rp) break; - if (pbest->rr_sim_status.can_run(rp, gstate.ncpus)) { - active.push_back(rp); + if (pbest->rr_sim_status.can_run(rp, gstate.ncpus) && sim_status.can_run(rp)) { + sim_status.activate(rp); pbest->rr_sim_status.activate(rp); } else { pbest->rr_sim_status.add_pending(rp); @@ -1307,7 +1329,8 @@ void CLIENT_STATE::rr_simulation() { if (log_flags.rr_simulation) { msg_printf(0, MSG_INFO, "[rr_sim] total: idle cpus %d, last active %d, active %d, shortfall %f", - nidle_cpus, last_active_size, (int)active.size(), cpu_shortfall + nidle_cpus, last_active_size, sim_status.nactive(), + cpu_shortfall ); msg_printf(0, MSG_INFO, diff --git a/lib/coproc.h b/lib/coproc.h index 4ae7ab9322..88996b0f57 100644 --- a/lib/coproc.h +++ b/lib/coproc.h @@ -70,6 +70,14 @@ struct COPROCS { bool sufficient_coprocs(COPROCS&, bool verbose); void reserve_coprocs(COPROCS&, bool verbose); void free_coprocs(COPROCS&, bool verbose); + void clone(COPROCS& c) { + for (unsigned int i=0; itype); + cp2->count = cp->count; + coprocs.push_back(cp2); + } + } }; // the following copied from /usr/local/cuda/include/driver_types.h