name = $name; $this->use_rec = false; $this->use_hyst_fetch = false; $this->cpu_sched_rr_only = false; $this->server_uses_workload = false; } } // a set of figures of merit // class RESULT { public $name; public $wasted_frac; public $idle_frac; public $share_violation; public $monotony; public $rpcs; function __construct($n) { $this->name = $n; $this->wasted_frac = 0; $this->idle_frac = 0; $this->share_violation = 0; $this->monotony = 0; $this->rpcs = 0; } function write($f) { if (is_numeric($this->name)) { fprintf($f, "%e", $this->name); } else { fprintf($f, "\"%s\"", $this->name); } fprintf($f, " wf %f if %f sv %f m %f r %f\n", $this->wasted_frac, $this->idle_frac, $this->share_violation, $this->monotony, $this->rpcs ); } function add($dir) { $f = fopen("$dir/results.dat", "r"); fscanf($f, "wf %f if %f sv %f m %f r %f", $wf, $if, $sv, $m, $r); $this->wasted_frac += $wf; $this->idle_frac += $if; $this->share_violation += $sv; $this->monotony += $m; $this->rpcs += $r; } function scale($n) { $this->wasted_frac /= $n; $this->idle_frac /= $n; $this->share_violation /= $n; $this->monotony /= $n; $this->rpcs /= $n; } } // do a simulation // function do_sim($in, $out, $policy) { global $duration; $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"; $cmd = "sim $args --infile_prefix $in/ --outfile_prefix $out/"; echo "cmd: $cmd\n"; system($cmd); } function write_gp_bar($fname, $title, $data_fname) { $f = fopen($fname, "w"); $s = <<write($f); $r2->write($f); fclose($f); $gp_fname = "$dir/cr.gp"; $png_fname = "$dir/cr.png"; write_gp_bar($gp_fname, $title, $data_fname); system("gnuplot < $gp_fname > $png_fname"); } function graph_n_results($title, $dir, $results) { $data_fname = "$dir/cr.dat"; $f = fopen($data_fname, "w"); foreach ($results as $r) { $r->write($f); } fclose($f); $gp_fname = "$dir/cr.gp"; $png_fname = "$dir/cr.png"; write_gp_line($gp_fname, $title, $data_fname); system("gnuplot < $gp_fname > $png_fname"); } // create output dir, do a simulation, accumulate results // function do_sim_aux($out_dir, $scenario, $policy, $pname, $sum) { $sim_out_dir = $out_dir."/".$pname."_".$scenario; @mkdir($sim_out_dir); do_sim($scenario, $sim_out_dir, $policy); $sum->add($sim_out_dir); return $sum; } function do_sim_param($out_dir, $scenario, $policy, $param, $sum) { $sim_out_dir = $out_dir."/".$scenario."_".$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); $cs = str_replace("PARAM", $param, $cs); file_put_contents($cs_fname, $cs); do_sim($scenario, $sim_out_dir, $policy); $r = new RESULT($param); $sum->add($sim_out_dir); return $sum; } ///////////// THE TOP-LEVEL FUNCTIONS //////////// // Compare 2 policies for a set of scenarios, and show the average results. // Outputs are stored in the given directory. // Subdirectories policy_scenario/ store individual sim outputs. // function compare_policies($title, $set, $p1, $p2, $out_dir) { $sum1 = new RESULT($p1->name); $sum2 = new RESULT($p2->name); @mkdir($out_dir); foreach ($set as $s) { $sum1 = do_sim_aux($out_dir, $s, $p1, "p1", $sum1); $sum2 = do_sim_aux($out_dir, $s, $p2, "p2", $sum2); } $sum1->scale(count($set)); $sum2->scale(count($set)); graph_2_results($title, $out_dir, $sum1, $sum2); } // For a given policy and a set of parameterized scenarios, // show the average results as a function of the parameter. // Outputs are stored in the given directory. // Subdirectories scenario_arg/ store individual sim outputs // function compare_params($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); } $results[] = $sum; } graph_n_results($title, $out_dir, $results); } ///////////// EXAMPLE USAGES //////////// // compare REC and debt scheduling for a set of scenarios // if (0) { $p1 = new POLICY("JS_LOCAL"); $p2 = new POLICY("JS_GLOBAL"); $p2->use_rec = true; compare_policies("Scenario 2", array("scen2"), $p1, $p2, "test1"); } // evaluate a policy over a set of parameterized policies // if (1) { $p = new POLICY(""); $p->use_rec = true; $lo = 2e9; $hi = 1e10; $inc = 1e9; compare_params("Scenario 3", array("s3"), $p, $lo, $hi, $inc, "test2"); } 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"); } if (0) { $p1 = new POLICY("JS_LOCAL"); $p2 = new POLICY("JS_GLOBAL"); $p2->use_rec = true; compare_policies("Scenario 4", array("scen4"), $p1, $p2, "test4"); } if (0) { $p1 = new POLICY("JS_LOCAL"); $p2 = new POLICY("JS_GLOBAL"); $p2->use_rec = true; compare_policies("Scenario 3", array("scen3"), $p1, $p2, "test5"); } ?>