diff --git a/checkin_notes b/checkin_notes index 9bbb597cea..787efbdc99 100644 --- a/checkin_notes +++ b/checkin_notes @@ -192,3 +192,13 @@ Charlie 18 Jan 2011 mac_installer/ release_boinc.sh + +David 18 Jan 2011 + - simulator work + + client/ + cpu_sched.cpp + work_fetch.h + sim.cpp + sim_control.cpp + client_types.cpp diff --git a/client/client_types.cpp b/client/client_types.cpp index 171ba15a73..ab9c4ed058 100644 --- a/client/client_types.cpp +++ b/client/client_types.cpp @@ -235,7 +235,7 @@ int PROJECT::parse_state(MIOFILE& in) { //#endif if (parse_double(buf, "", ati_pwf.backoff_interval)) continue; if (parse_double(buf, "", ati_pwf.backoff_time)) continue; - if (parse_double(buf, "", x)) continue; + if (parse_double(buf, "", resource_share)) continue; // not authoritative if (parse_double(buf, "", duration_correction_factor)) continue; if (parse_bool(buf, "attached_via_acct_mgr", attached_via_acct_mgr)) continue; diff --git a/client/cpu_sched.cpp b/client/cpu_sched.cpp index 0358d49f24..23f17a287e 100644 --- a/client/cpu_sched.cpp +++ b/client/cpu_sched.cpp @@ -79,6 +79,8 @@ using std::vector; using std::list; +double rec_half_life = 10*86400; // half-life of recent est credit + #define DEADLINE_CUSHION 0 // try to finish jobs this much in advance of their deadline @@ -591,7 +593,7 @@ static void update_rec() { gstate.now, gstate.debt_interval_start, x, - REC_HALF_LIFE, + rec_half_life, p->pwf.rec, p->pwf.rec_time ); diff --git a/client/sim.cpp b/client/sim.cpp index afd0d1b141..ce9dbb7d76 100644 --- a/client/sim.cpp +++ b/client/sim.cpp @@ -56,6 +56,12 @@ // simulate use of EDF sim by scheduler // [--cpu_sched_rr_only] // use only RR scheduling +// [--use_rec] +// client scheduling is based on recent estimated credit (REC) +// [--use_hyst_fetch] +// client work fetch uses hysteresis +// [--rec_half_life X] +// half-life of recent est credit #include "error_numbers.h" #include "str_util.h" @@ -1059,12 +1065,29 @@ void simulate() { "preferences\n" " buf min %f max %f\n" " cpu sched period %f\n" + "policies\n" + " WRR only: %s\n" + " scheduler EDF sim: %s\n" + " hysteresis work fetch: %s\n" + " REC-based scheduling: %s\n", + gstate.work_buf_min(), gstate.work_buf_total(), + gstate.global_prefs.cpu_scheduling_period(), + cpu_sched_rr_only?"yes":"no", + server_uses_workload?"yes":"no", + use_hyst_fetch?"yes":"no", + use_rec?"yes":"no" + ); + if (use_rec) { + fprintf(summary_file, + " REC half-life: %f\n", + rec_half_life + ); + } + fprintf(summary_file, "sim params\n" " delta %f duration %f\n" "starting simulation\n" "-------------------\n", - gstate.work_buf_min(), gstate.work_buf_total(), - gstate.global_prefs.cpu_scheduling_period(), delta, duration ); while (1) { @@ -1372,6 +1395,8 @@ int main(int argc, char** argv) { use_rec = true; } else if (!strcmp(opt, "--use_hyst_fetch")) { use_hyst_fetch = true; + } else if (!strcmp(opt, "--rec_half_life")) { + rec_half_life = atof(argv[i++]); } else { usage(argv[0]); } diff --git a/client/sim_control.php b/client/sim_control.php index cc31c404a2..49ddc01874 100644 --- a/client/sim_control.php +++ b/client/sim_control.php @@ -18,12 +18,14 @@ // Compare 2 policies over a set of scenarios. // Show the average results as side-by-side bar graphs // -// compare_params() +// compare_scenario_params() // For a given policy and a set of parameterized scenarios, // show the average results as a function of the parameter. // Show the figures of merit as line graphs. $duration = 864000; // sim duration +$delta = 60; // time step +$rec_half_life = 10*86400; // a set of scheduling policies // @@ -63,7 +65,7 @@ class RESULT { } function write($f) { if (is_numeric($this->name)) { - fprintf($f, "%e", $this->name); + fprintf($f, "%d", $this->name); } else { fprintf($f, "\"%s\"", $this->name); } @@ -97,14 +99,14 @@ class RESULT { // do a simulation // function do_sim($in, $out, $policy) { - global $duration; + global $duration, $delta, $rec_half_life; $args = ""; if ($policy->use_rec) $args .= " --use_rec"; if ($policy->use_hyst_fetch) $args .= " --use_hyst_fetch"; if ($policy->cpu_sched_rr_only) $args .= " --cpu_sched_rr_only"; if ($policy->server_uses_workload) $args .= " --server_uses_workload"; - $args .= " --duration $duration"; + $args .= " --duration $duration --delta $delta --rec_half_life $rec_half_life"; $cmd = "sim $args --infile_prefix $in/ --outfile_prefix $out/"; echo "cmd: $cmd\n"; @@ -155,9 +157,11 @@ EOT; } // display 2 groups of N results as line graphs. -// Show only 1 figure of merit (waste). +// Show only 1 figure of merit ($col). // -function write_gp_line2($fname, $title, $xlabel, $lab1, $lab2, $data1, $data2) { +function write_gp_line2( + $fname, $title, $xlabel, $lab1, $lab2, $data1, $data2, $col +) { $f = fopen($fname, "w"); $s = << $png_fname"); } -function graph_n_results2($title, $xlabel, $lab1, $lab2, $dir, $results1, $results2) { +function graph_n_results2( + $title, $xlabel, $lab1, $lab2, $dir, $results1, $results2, $col +) { for ($i=0; $i<2; $i++) { $data_fname = "$dir/cr_$i.dat"; $f = fopen($data_fname, "w"); @@ -210,7 +217,10 @@ function graph_n_results2($title, $xlabel, $lab1, $lab2, $dir, $results1, $resul } $gp_fname = "$dir/cr.gp"; $png_fname = "$dir/cr.png"; - write_gp_line2($gp_fname, $title, $xlabel, $lab1, $lab2, "$dir/cr_0.dat", "$dir/cr_1.dat"); + write_gp_line2( + $gp_fname, $title, $xlabel, $lab1, $lab2, + "$dir/cr_0.dat", "$dir/cr_1.dat", $col + ); system("gnuplot < $gp_fname > $png_fname"); } @@ -224,12 +234,15 @@ function do_sim_aux($out_dir, $scenario, $policy, $pname, $sum) { return $sum; } -function do_sim_param($out_dir, $scenario, $policy, $param, $sum) { +// substitute a param into scenario and run sim +// +function do_sim_scenario_param($out_dir, $scenario, $policy, $param, $sum) { $sim_out_dir = $out_dir."/".$scenario."_".$policy->name."_".$param; @mkdir($sim_out_dir); $cs_template_fname = "$scenario/client_state_template.xml"; $cs_fname = "$scenario/client_state.xml"; $cs = file_get_contents($cs_template_fname); + if (!$cs) die("no file $cs_template_fname"); $cs = str_replace("PARAM", $param, $cs); file_put_contents($cs_fname, $cs); do_sim($scenario, $sim_out_dir, $policy); @@ -238,6 +251,16 @@ function do_sim_param($out_dir, $scenario, $policy, $param, $sum) { return $sum; } +// do a sim with a policy parameter +// +function do_sim_policy_param($out_dir, $scenario, $policy, $param, $sum) { + $sim_out_dir = $out_dir."/".$scenario."_".$policy->name."_".$param; + @mkdir($sim_out_dir); + do_sim($scenario, $sim_out_dir, $policy); + $sum->add($sim_out_dir); + return $sum; +} + ///////////// THE TOP-LEVEL FUNCTIONS //////////// // Compare 2 policies for a set of scenarios, and show the average results. @@ -262,13 +285,13 @@ function compare_policies($title, $set, $p1, $p2, $out_dir) { // Outputs are stored in the given directory. // Subdirectories scenario_arg/ store individual sim outputs // -function compare_params1($title, $set, $policy, $lo, $hi, $inc, $out_dir) { +function compare_scenario_params1($title, $set, $policy, $lo, $hi, $inc, $out_dir) { @mkdir($out_dir); $results = array(); for ($x = $lo; $x <= $hi; $x += $inc) { $sum = new RESULT($x); foreach ($set as $s) { - $sum = do_sim_param($out_dir, $s, $policy, $x, $sum); + $sum = do_sim_scenario_param($out_dir, $s, $policy, $x, $sum); } $results[] = $sum; } @@ -277,23 +300,47 @@ function compare_params1($title, $set, $policy, $lo, $hi, $inc, $out_dir) { // same, but compare 2 policies and graph only wasted CPU // -function compare_params2($title, $xlabel, $lab1, $lab2, $set, $p1, $p2, $lo, $hi, $inc, $out_dir) { +function compare_scenario_params2($title, $xlabel, $lab1, $lab2, $set, $p1, $p2, $lo, $hi, $inc, $out_dir) { @mkdir($out_dir); $rr1 = array(); $rr2 = array(); for ($x = $lo; $x <= $hi; $x += $inc) { $sum = new RESULT($x); foreach ($set as $s) { - $sum = do_sim_param($out_dir, $s, $p1, $x, $sum); + $sum = do_sim_scenario_param($out_dir, $s, $p1, $x, $sum); } $rr1[] = $sum; $sum = new RESULT($x); foreach ($set as $s) { - $sum = do_sim_param($out_dir, $s, $p2, $x, $sum); + $sum = do_sim_scenario_param($out_dir, $s, $p2, $x, $sum); } $rr2[] = $sum; } - graph_n_results2($title, $xlabel, $lab1, $lab2, $out_dir, $rr1, $rr2); + graph_n_results2($title, $xlabel, $lab1, $lab2, $out_dir, $rr1, $rr2, 3); +} + +// compare two policies, varying rec_half_life +// +function compare_policy_params($title, $xlabel, $lab1, $lab2, $set, $p1, $p2, $lo, $hi, $inc, $out_dir) { + global $rec_half_life; + + @mkdir($out_dir); + $rr1 = array(); + $rr2 = array(); + for ($x = $lo; $x <= $hi; $x += $inc) { + $rec_half_life = $x; + $sum = new RESULT($x); + foreach ($set as $s) { + $sum1 = do_sim_policy_param($out_dir, $s, $p1, $x, $sum); + } + $rr1[] = $sum; + $sum = new RESULT($x); + foreach ($set as $s) { + $sum1 = do_sim_policy_param($out_dir, $s, $p2, $x, $sum); + } + $rr2[] = $sum; + } + graph_n_results2($title, $xlabel, $lab1, $lab2, $out_dir, $rr1, $rr2, 7); } ///////////// EXAMPLE USAGES //////////// @@ -313,25 +360,14 @@ if (0) { $lo = 2e9; $hi = 1e10; $inc = 1e9; - compare_params1("Scenario 3", array("s3"), $p, $lo, $hi, $inc, "test2"); + compare_scenario_params1("Scenario 3", array("s3"), $p, $lo, $hi, $inc, "test2"); } -// compare WRR and EDF if (1) { - $p1 = new POLICY("DC_SIM"); - $p1->server_uses_workload = true; - $p2 = new POLICY("DC_APPROX"); - $lo = 1000; - $hi = 2000; - $inc = 100; - compare_params2("Wasted processing", "Job deadline", "DC_SIM", "DC_APPROX", array("scen5"), $p1, $p2, $lo, $hi, $inc, "test6"); -} - -if (0) { $p1 = new POLICY("WF_ORIG"); $p2 = new POLICY("WF_HYST"); $p2->use_hyst_fetch = true; - compare_policies("Scenario 1", array("scen1"), $p1, $p2, "test3"); + compare_policies("Scenario 4", array("scen4"), $p1, $p2, "test3"); } if (0) { @@ -340,10 +376,46 @@ if (0) { $p2->use_rec = true; compare_policies("Scenario 4", array("scen4"), $p1, $p2, "test4"); } + if (0) { + $duration = 50* 86400; $p1 = new POLICY("JS_LOCAL"); $p2 = new POLICY("JS_GLOBAL"); $p2->use_rec = true; compare_policies("Scenario 3", array("scen3"), $p1, $p2, "test5"); } + +// compare WRR and EDF +if (0) { + $p1 = new POLICY("JS_LOCAL"); + $p1->use_rec = true; + $p1->use_hyst_fetch = true; + $p1->cpu_sched_rr_only = true; + $p2 = new POLICY("JS_WRR"); + $p2->use_rec = true; + $p2->use_hyst_fetch = true; + $lo = 1000; + $hi = 2000; + $inc = 100; + compare_scenario_params2("Wasted processing", "Latency bound", "JS_WRR", "JS_LOCAL", array("scen5"), $p1, $p2, $lo, $hi, $inc, "test6"); +} + +// compare rec and debt over a range of rec_half_life +if (0) { + $p1 = new POLICY("JS_LOCAL"); + $p2 = new POLICY("JS_GLOBAL"); + $p2->use_rec = true; + $lo = 5*86400; + $hi = 40*86400; + $inc = 5*86400; + $duration = 50* 86400; + compare_policy_params("Resource share violation", "REC half-life", "JS_LOCAL", "JS_GLOBAL", array("scen3"), $p1, $p2, $lo, $hi, $inc, "test7"); +} + +if (0) { + $p1 = new POLICY("JS_LOCAL + WF_ORIG"); + $p2 = new POLICY("JS_GLOBAL + WF_HYSTERESIS"); + $p2->use_rec = true; + compare_policies("Scenario 4", array("scen4"), $p1, $p2, "test8"); +} ?> diff --git a/client/work_fetch.h b/client/work_fetch.h index f0897553c1..5c103d5905 100644 --- a/client/work_fetch.h +++ b/client/work_fetch.h @@ -25,8 +25,7 @@ extern bool use_rec; #define USE_REC -#define REC_HALF_LIFE (10*86400) -//#define REC_HALF_LIFE (1*86400) +extern double rec_half_life; extern bool use_hyst_fetch; diff --git a/doc/projects.inc b/doc/projects.inc index 79c26c16a0..85257bd091 100644 --- a/doc/projects.inc +++ b/doc/projects.inc @@ -367,14 +367,14 @@ $math = array( // "Find prime numbers of the form k*2n-1", // "" // ), - array( - "Rectilinear Crossing Number", - "http://dist.ist.tugraz.at/cape5/", - "Graz University of Technology (Austria)", - "Mathematics", - "What is the least number of crossings a straight-edge drawing of the complete graph on top of a set of n points in the plane obtains? From very recent (not even published yet) mathematical considerations the rectilinear crossing numbers for n=19 and n=21 are also known. So the most tantalizing problem now is to determine the true value for n=18, which is the main focus of this project.", - "" - ), +// array( +// "Rectilinear Crossing Number", +// "http://dist.ist.tugraz.at/cape5/", +// "Graz University of Technology (Austria)", +// "Mathematics", +// "What is the least number of crossings a straight-edge drawing of the complete graph on top of a set of n points in the plane obtains? From very recent (not even published yet) mathematical considerations the rectilinear crossing numbers for n=19 and n=21 are also known. So the most tantalizing problem now is to determine the true value for n=18, which is the main focus of this project.", +// "" +// ), array( "Chess960@home", "http://www.chess960athome.org/alpha/",