*** empty log message ***

svn path=/trunk/boinc/; revision=6356
This commit is contained in:
David Anderson 2005-06-15 21:03:43 +00:00
parent 7aa4ec69bf
commit e39cec83f0
4 changed files with 69 additions and 54 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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<double, RESULT*> results_by_deadline;
std::set<PROJECT*> 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 <double> booked_to;
std::map<double, RESULT*>::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<RESULT*>::iterator it_u;
for (it_u = results.begin(); it_u != results.end(); ++it_u) {
rp = *it_u;
for (i=0; i<results.size(); i++) {
rp = results[i];
if (rp->computing_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; i<ncpus; i++) {
booked_to.push_back(gstate.now);
}
for (
it = results_by_deadline.begin();
it != results_by_deadline.end() && !should_not_fetch_work;
it++
) {
rp = (*it).second;
if (rp->project->non_cpu_intensive) continue;
if (rp->computing_done()) continue;
double lowest_book = booked_to[0];
int lowest_booked_cpu = 0;
for (i=1; i<ncpus; i++) {
if (booked_to[i] < lowest_book) {
lowest_book = booked_to[i];
lowest_booked_cpu = i;
}
}
booked_to[lowest_booked_cpu] += rp->estimated_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; i<ncpus; i++) {
booked_to.push_back(gstate.now);
}
// 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
//
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 (i=1; i<ncpus; i++) {
if (booked_to[i] < lowest_book) {
lowest_book = booked_to[i];
lowest_booked_cpu = i;
}
}
booked_to[lowest_booked_cpu] += rp->estimated_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