- scheduler: added

- config option <matchmaker> for matchmaker scheduling
    - config options <mm_min_slots>, <mm_max_slots>, <job_size_matching>
        to control matchmaker scheduling
- scheduler: tweaks to matchmaker scheduling from Kevin Reed
- web: fixes to alternative stylesheet from Simek

svn path=/trunk/boinc/; revision=15281
This commit is contained in:
David Anderson 2008-05-23 16:13:30 +00:00
parent d92eedb96a
commit 49eb1246cf
5 changed files with 120 additions and 104 deletions

View File

@ -4252,3 +4252,17 @@ David May 22 2008
client_state.C,h
cpu_sched.C
cs_prefs.C
David May 23 2008
- scheduler: added
- config option <matchmaker> for matchmaker scheduling
- config options <mm_min_slots>, <mm_max_slots>, <job_size_matching>
to control matchmaker scheduling
- scheduler: tweaks to matchmaker scheduling from Kevin Reed
- web: fixes to alternative stylesheet from Simek
html/user/
style2.css
sched/
sched_config.C,h
sched_send.C

View File

@ -22,6 +22,8 @@ input, select {
border: 1px solid grey;
background-color: #eeeeee;
padding: 3px;
font-size: 11px;
margin: 2px;
}
input:hover, input:active, select:hover {
@ -30,7 +32,7 @@ input:hover, input:active, select:hover {
input.btn {
margin: 3px 0px;
padding: 2px 4px;
padding: 2px 5px;
}
h1 {
@ -200,33 +202,30 @@ tr.message {
overflow: auto;
}
blockquote {
blockquote.postbody {
border-left: 2px solid #00A0E3;
background: #d6eef8;
padding: 3px;
background-color: #F0F8FF;
padding: 4px 8px;
margin-bottom: 0px;
margin-left: 20px;
margin-right: 60px;
font-style: italic;
}
#blockquote.postbody {
border-style: inset;
border-color: blue;
background-color: rgb(240,240,255);
padding-left: 5px;
padding-bottom: 0px;
margin-bottom: 0px;
margin-left: 15px;
margin-right: 140px;
font-style: oblique
}
#thread {
width: 100%;
table-layout: fixed;
overflow: overflow;
}
#threadauthor input {
background-color: white;
}
td.lastpost {
background-color: white;
}
.sigdelim {
width: 60%;
height: 1px;
@ -252,9 +251,9 @@ td.postbody {
}
td.postfooter{
background-color: #F0F8FF;
background-color: #EEEEEE;
border-top: 1px solid #00A0E3;
border-left: 1px solid #00A0E3;
border-left: none;
border-right: none;
border-bottom: none;
padding-left: 6px;

View File

@ -50,6 +50,9 @@ int SCHED_CONFIG::parse(FILE* f) {
int retval;
regex_t re;
// Don't bother to initialize to zero since it's a global.
// If this ever changes, need to initialize
//
mf.init_file(f);
max_wus_to_send = 10;
default_disk_max_used_gb = 100.;
@ -59,7 +62,6 @@ int SCHED_CONFIG::parse(FILE* f) {
fuh_debug_level = MSG_NORMAL;
strcpy(httpd_user, "apache");
max_ncpus = MAX_NCPUS;
debug_version_select = false;
if (!xp.parse_start("boinc")) return ERR_XML_PARSE;
if (!xp.parse_start("config")) return ERR_XML_PARSE;
@ -183,8 +185,12 @@ int SCHED_CONFIG::parse(FILE* f) {
}
continue;
}
if (xp.parse_bool(tag, "matchmaker", matchmaker)) continue;
if (xp.parse_int(tag, "mm_min_slots", mm_min_slots)) continue;
if (xp.parse_int(tag, "mm_max_slots", mm_max_slots)) continue;
if (xp.parse_bool(tag, "job_size_matching", job_size_matching)) continue;
if (xp.parse_bool(tag, "debug_version_select", debug_version_select)) continue;
if (xp.parse_bool(tag, "debug_assignment", debug_assignment)) continue;
if (xp.parse_bool(tag, "debug_prefs", debug_prefs)) continue;

View File

@ -120,7 +120,11 @@ public:
int max_ncpus;
vector<regex_t> ban_os;
vector<regex_t> ban_cpu;
bool matchmaker;
int mm_min_slots;
int mm_max_slots;
bool job_size_matching;
// log flags
//
bool debug_version_select;

View File

@ -59,11 +59,8 @@ using namespace std;
#define FCGI_ToFILE(x) (x)
#endif
//#define MATCHMAKER
#ifdef MATCHMAKER
void send_work_matchmaker(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply);
#endif
int preferred_app_message_index=0;
@ -1206,6 +1203,59 @@ static void get_running_frac(SCHEDULER_REPLY& reply) {
if (reply.wreq.running_frac > 1) reply.wreq.running_frac = 1;
}
static void send_work_old(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
reply.wreq.beta_only = false;
reply.wreq.user_apps_only = true;
// give top priority to results that require a 'reliable host'
//
if (reply.wreq.host_info.reliable) {
reply.wreq.reliable_only = true;
reply.wreq.infeasible_only = false;
scan_work_array(sreq, reply);
}
reply.wreq.reliable_only = false;
// give 2nd priority to results for a beta app
// (projects should load beta work with care,
// otherwise your users won't get production work done!
//
if (reply.wreq.host_info.allow_beta_work) {
reply.wreq.beta_only = true;
if (config.debug_send) {
log_messages.printf(MSG_DEBUG,
"[HOST#%d] will accept beta work. Scanning for beta work.\n",
reply.host.id
);
}
scan_work_array(sreq, reply);
}
reply.wreq.beta_only = false;
// give next priority to results that were infeasible for some other host
//
reply.wreq.infeasible_only = true;
scan_work_array(sreq, reply);
reply.wreq.infeasible_only = false;
scan_work_array(sreq, reply);
// If user has selected apps but will accept any,
// and we haven't found any jobs for selected apps, try others
//
if (!reply.wreq.nresults && reply.wreq.host_info.allow_non_preferred_apps ) {
reply.wreq.user_apps_only = false;
preferred_app_message_index = reply.wreq.no_work_messages.size();
if (config.debug_send) {
log_messages.printf(MSG_DEBUG,
"[HOST#%d] is looking for work from a non-preferred application\n",
reply.host.id
);
}
scan_work_array(sreq, reply);
}
}
void send_work(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
if (sreq.work_req_seconds <= 0) return;
@ -1226,12 +1276,8 @@ void send_work(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
if (config.debug_send) {
log_messages.printf(MSG_DEBUG,
"%s matchmaking scheduling; %s EDF sim\n",
#ifdef MATCHMAKER
"Using",
#else
"Not using",
#endif
"%s matchmaker scheduling; %s EDF sim\n",
config.matchmaker?"Using":"Not using",
config.workload_sim?"Using":"Not using"
);
log_messages.printf(MSG_DEBUG,
@ -1276,67 +1322,16 @@ void send_work(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
if (config.locality_scheduling) {
reply.wreq.infeasible_only = false;
send_work_locality(sreq, reply);
} else {
#ifdef MATCHMAKER
} else if (config.matchmaker) {
send_work_matchmaker(sreq, reply);
#else
reply.wreq.beta_only = false;
reply.wreq.user_apps_only = true;
// give top priority to results that require a 'reliable host'
//
if (reply.wreq.host_info.reliable) {
reply.wreq.reliable_only = true;
reply.wreq.infeasible_only = false;
scan_work_array(sreq, reply);
}
reply.wreq.reliable_only = false;
// give 2nd priority to results for a beta app
// (projects should load beta work with care,
// otherwise your users won't get production work done!
//
if (reply.wreq.host_info.allow_beta_work) {
reply.wreq.beta_only = true;
if (config.debug_send) {
log_messages.printf(MSG_DEBUG,
"[HOST#%d] will accept beta work. Scanning for beta work.\n",
reply.host.id
);
}
scan_work_array(sreq, reply);
}
reply.wreq.beta_only = false;
// give next priority to results that were infeasible for some other host
//
reply.wreq.infeasible_only = true;
scan_work_array(sreq, reply);
reply.wreq.infeasible_only = false;
scan_work_array(sreq, reply);
// If user has selected apps but will accept any,
// and we haven't found any jobs for selected apps, try others
//
if (!reply.wreq.nresults && reply.wreq.host_info.allow_non_preferred_apps ) {
reply.wreq.user_apps_only = false;
preferred_app_message_index = reply.wreq.no_work_messages.size();
if (config.debug_send) {
log_messages.printf(MSG_DEBUG,
"[HOST#%d] is looking for work from a non-preferred application\n",
reply.host.id
);
}
scan_work_array(sreq, reply);
}
#endif
} else {
send_work_old(sreq, reply);
}
explain_to_user(reply);
}
#ifdef MATCHMAKER
// Matchmaker scheduling code follows
struct JOB{
int index;
@ -1420,30 +1415,27 @@ bool JOB::get_score(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
score = 1;
// check if user has selected apps
// check if user has selected apps,
// and send beta work to beta users
//
if (!reply.wreq.host_info.allow_beta_work || config.distinct_beta_apps) {
if (app_not_selected(wu, sreq, reply)) {
if (!reply.wreq.host_info.allow_non_preferred_apps) {
return false;
}
} else {
if (reply.wreq.host_info.allow_non_preferred_apps) {
score += 1;
}
}
}
// if it's a beta user, try to send beta jobs
//
if (app->beta) {
if(app->beta && !config.distinct_beta_apps) {
if (reply.wreq.host_info.allow_beta_work) {
score += 1;
} else {
return false;
}
} else {
if (app_not_selected(wu, sreq, reply)) {
if (!reply.wreq.host_info.allow_non_preferred_apps) {
return false;
} else {
// Allow work to be sent, but it will not get a bump in its score
}
} else {
score += 1;
}
}
// if job needs to get done fast, send to fast/reliable host
//
if (reply.wreq.host_info.reliable && (wu_result.need_reliable)) {
@ -1636,8 +1628,10 @@ void JOB_SET::send(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
void send_work_matchmaker(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
int i, slots_scanned=0, slots_locked=0;
JOB_SET jobs;
int min_slots = 20;
int max_slots = 50;
int min_slots = config.mm_min_slots;
if (!min_slots) min_slots = ssp->max_wu_results/2;
int max_slots = config.mm_max_slots;
if (!max_slots) max_slots = ssp->max_wu_results;
int max_locked = 10;
int pid = getpid();
@ -1668,7 +1662,7 @@ void send_work_matchmaker(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
"score for %s: %f\n", wu_result.workunit.name, job.score
);
}
if (job.score > jobs.lowest_score()) {
if (job.score > jobs.lowest_score() || !jobs.request_satisfied()) {
ssp->wu_results[i].state = pid;
unlock_sema();
if (wu_is_infeasible_slow(wu_result, sreq, reply)) {
@ -1692,6 +1686,5 @@ void send_work_matchmaker(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
);
}
}
#endif
const char *BOINC_RCSID_32dcd335e7 = "$Id$";