function canonical() { global $DEBUG, $streams, $nodes; // extern int global $s1, $s2, $s3, $s4; // extern char global $job; // extern JOB_TYPE * global $node; // extern NODE_TYPE * $k = 0; // int $c = 0; // int $X = 0.0; // double $Xsat = 0.0; // double; $Dsat = 0.0; $sumR = array(); // double [MAXSTREAMS]; $devU = 0.0; // double $jobname = ""; // char [MAXBUF]; $p = "canonical()"; // = 0.0; // double if ($DEBUG) { debug($p, "Entering"); } for ($c = 0; $c < $streams; $c++) { $sumR[$c] = 0.0; $X = $job[$c]->trans->arrival_rate; /* find saturation device */ for ($k = 0; $k < $nodes; $k++) { if ($node[$k]->demand[$c] > $Dsat) { $Dsat = $node[$k]->demand[$c]; } } if ($Dsat == 0) { $s1 = sprintf("Dsat = %3.3f", $Dsat); errmsg($p, $s1); } $Xsat = 1.0 / $Dsat; $job[$c]->trans->saturation_rate = $Xsat; if ($X > $job[$c]->trans->saturation_rate) { $s1 = sprintf("\nArrival rate %3.3f exceeds system saturation %3.3f = 1/%3.3f", $X, $Xsat, $Dsat); errmsg($p, $s1); } for ($k = 0; $k < $nodes; $k++) { $node[$k]->utiliz[$c] = $X * $node[$k]->demand[$c]; $devU = sumU($k); if ($devU > 1.0) { $s1 = sprintf("\nTotal utilization of node %s is %2.2f%% (>100%%)", $node[$k]->devname, $devU * 100.0); errmsg($p, $s1); } if ($DEBUG) { printf("Tot Util: %3.4f for %s\n", $devU, $node[$k]->devname); } switch ($node[$k]->sched) { case FCFS: case PSHR: case LCFS: $node[$k]->resit[$c] = $node[$k]->demand[$c] / (1.0 - $devU); $node[$k]->qsize[$c] = $X * $node[$k]->resit[$c]; break; case ISRV: $node[$k]->resit[$c] = $node[$k]->demand[$c]; $node[$k]->qsize[$c] = $node[$k]->utiliz[$c]; break; default: typetostr($s1, $node[$k]->sched); $s2 = sprintf("Unknown queue type: %s", $s1); errmsg($p, $s2); break; } $sumR[$c] += $node[$k]->resit[$c]; } /* loop over k */ $job[$c]->trans->sys->thruput = $X; $job[$c]->trans->sys->response = $sumR[$c]; $job[$c]->trans->sys->residency = $X * $sumR[$c]; if ($DEBUG) { getjob_name($jobname, $c); printf("\tX[%s]: %3.4f\n", $jobname, $job[$c]->trans->sys->thruput); printf("\tR[%s]: %3.4f\n", $jobname, $job[$c]->trans->sys->response); printf("\tN[%s]: %3.4f\n", $jobname, $job[$c]->trans->sys->residency); } } /* loop over c */ if ($DEBUG) { debug($p, "Exiting"); } }
function approx() { global $DEBUG, $iterations, $streams, $nodes; // extern int global $s1, $s2, $s3, $s4; // extern char[] global $tolerance; // extern double global $job; // extern JOB_TYPE * global $node; // extern NODE_TYPE * $k = 0; // int $c = 0; // int $should_be_class = 0; // int $sumR = array(); // double[MAXSTREAMS]; $delta = 2 * TOL; // double $iterate = 0; // int $jobname = ""; // char[MAXBUF]; $last = NULL; // NODE_TYPE * $p = "approx()"; // char $N = 0.0; // double; if ($DEBUG) { debug($p, "Entering"); } if ($nodes == 0 || $streams == 0) { errmsg($p, "Network nodes and streams not defined."); } //if ((last = (NODE_TYPE *) calloc(sizeof(NODE_TYPE), nodes)) == NULL) // errmsg(p, "Node (last) allocation failed!\n"); $last = array(); for ($c = 0; $c < $nodes; $c++) { $last[$c] = new NODE_TYPE(); } $iterations = 0; if ($DEBUG) { $s1 = sprintf("\nIteration: %d", $iterations); debug($p, $s1); $s1 = ""; } /* initialize all queues */ for ($c = 0; $c < $streams; $c++) { $should_be_class = $job[$c]->should_be_class; for ($k = 0; $k < $nodes; $k++) { switch ($should_be_class) { case TERM: $node[$k]->qsize[$c] = $job[$c]->term->pop / $nodes; $last[$k]->qsize[$c] = $node[$k]->qsize[$c]; break; case BATCH: $node[$k]->qsize[$c] = $job[$c]->batch->pop / $nodes; $last[$k]->qsize[$c] = $node[$k]->qsize[$c]; break; default: break; } if ($DEBUG) { getjob_name($jobname, $c); $s2 = sprintf("Que[%s][%s]: %3.4f (D=%f)", $node[$k]->devname, $jobname, $node[$k]->qsize[$c], $delta); debug($p, $s2); $s2 = ""; $jobname = ""; } } /* over k */ } /* over c */ do { $iterations++; if ($DEBUG) { $s1 = sprintf("\nIteration: %d", $iterations); debug($p, $s1); $s1 = ""; } for ($c = 0; $c < $streams; $c++) { getjob_name($jobname, $c); $sumR[$c] = 0.0; if ($DEBUG) { $s1 = sprintf("\nStream: %s", $jobname); debug($p, $s1); $s1 = ""; } $should_be_class = $job[$c]->should_be_class; for ($k = 0; $k < $nodes; $k++) { if ($DEBUG) { $s2 = sprintf("Que[%s][%s]: %3.4f (D=%1.5f)", $node[$k]->devname, $jobname, $node[$k]->qsize[$c], $delta); debug($p, $s2); $s1 = ""; } /* approximate avg queue length */ switch ($should_be_class) { case TERM: $N = $job[$c]->term->pop; $node[$k]->avqsize[$c] = sumQ($k, $c) + $node[$k]->qsize[$c] * ($N - 1.0) / $N; break; case BATCH: $N = $job[$c]->batch->pop; $node[$k]->avqsize[$c] = sumQ($k, $c) + $node[$k]->qsize[$c] * ($N - 1.0) / $N; break; default: typetostr($s1, $should_be_class); $s2 = sprintf("Unknown should_be_class: %s", $s1); errmsg($p, $s2); $s2 = ""; break; } if ($DEBUG) { $s2 = sprintf("<Q>[%s][%s]: %3.4f (D=%1.5f)", $node[$k]->devname, $jobname, $node[$k]->avqsize[$c], $delta); debug($p, $s2); $s2 = ""; } /* residence times */ switch ($node[$k]->sched) { case FCFS: case PSHR: case LCFS: $node[$k]->resit[$c] = $node[$k]->demand[$c] * ($node[$k]->avqsize[$c] + 1.0); break; case ISRV: $node[$k]->resit[$c] = $node[$k]->demand[$c]; break; default: typetostr($s1, $node[$k]->sched); $s2 = sprintf("Unknown queue type: %s", $s1); errmsg($p, $s2); break; } $sumR[$c] += $node[$k]->resit[$c]; if ($DEBUG) { printf("\tTot ResTime[%s] = %3.4f\n", $jobname, $sumR[$c]); printf("\tnode[%s].qsize[%s] = %3.4f\n", $node[$k]->devname, $jobname, $node[$k]->qsize[$c]); printf("\tnode[%s].demand[%s] = %3.4f\n", $node[$k]->devname, $jobname, $node[$k]->demand[$c]); printf("\tnode[%s].resit[%s] = %3.4f\n", $node[$k]->devname, $jobname, $node[$k]->resit[$c]); } } /* over k */ /* system throughput, residency & response-time */ switch ($should_be_class) { case TERM: $job[$c]->term->sys->thruput = $job[$c]->term->pop / ($sumR[$c] + $job[$c]->term->think); $job[$c]->term->sys->response = $job[$c]->term->pop / $job[$c]->term->sys->thruput - $job[$c]->term->think; $job[$c]->term->sys->residency = $job[$c]->term->pop - $job[$c]->term->sys->thruput * $job[$c]->term->think; if ($DEBUG) { $s2 = sprintf("\tTERM<X>[%s]: %5.4f", $jobname, $job[$c]->term->sys->thruput); debug($p, $s2); $s2 = ""; $s2 = sprintf("\tTERM<R>[%s]: %5.4f", $jobname, $job[$c]->term->sys->response); debug($p, $s2); $s2 = ""; } break; case BATCH: $job[$c]->batch->sys->thruput = $job[$c]->batch->pop / $sumR[$c]; $job[$c]->batch->sys->response = $job[$c]->batch->pop / $job[$c]->batch->sys->thruput; $job[$c]->batch->sys->residency = $job[$c]->batch->pop; if ($DEBUG) { $s2 = sprintf("\t<X>[%s]: %3.4f", $jobname, $job[$c]->batch->sys->thruput); debug($p, $s2); $s2 = ""; $s2 = sprintf("\t<R>[%s]: %3.4f", $jobname, $job[$c]->batch->sys->response); debug($p, $s2); $s2 = ""; } break; default: $s1 = sprintf("Unknown should_be_class: %s", $should_be_class); errmsg($p, $s1); break; } $jobname = ""; } /* over c */ /* update queue sizes */ for ($c = 0; $c < $streams; $c++) { getjob_name($jobname, $c); $should_be_class = $job[$c]->should_be_class; $iterate = FALSE; if ($DEBUG) { $s1 = sprintf("Updating queues of \"%s\"", $jobname); printf("\n"); debug($p, $s1); $s1 = ""; } for ($k = 0; $k < $nodes; $k++) { switch ($should_be_class) { case TERM: $node[$k]->qsize[$c] = $job[$c]->term->sys->thruput * $node[$k]->resit[$c]; break; case BATCH: $node[$k]->qsize[$c] = $job[$c]->batch->sys->thruput * $node[$k]->resit[$c]; break; default: $s1 = sprintf("Unknown should_be_class: %s", $should_be_class); errmsg($p, $s1); break; } /* check convergence */ $delta = abs((double) ($last[$k]->qsize[$c] - $node[$k]->qsize[$c])); if ($delta > $tolerance) { /* for any node */ $iterate = TRUE; } /* but complete all queue updates */ $last[$k]->qsize[$c] = $node[$k]->qsize[$c]; if ($DEBUG) { $s2 = sprintf("Que[%s][%s]: %3.4f (D=%1.5f)", $node[$k]->devname, $jobname, $node[$k]->qsize[$c], $delta); debug($p, $s2); $s2 = ""; } } /* over k */ $jobname = ""; } /* over c */ if ($DEBUG) { debug($p, "Update complete"); } } while ($iterate); /* cleanup */ if ($last) { $last = NULL; } if ($DEBUG) { debug($p, "Exiting"); } }
function print_node_stats($c, $should_be_class) { global $s1, $s4, $tUnit, $wUnit; // extern char[] global $DEBUG, $demand_ext, $nodes; // extern int global $job; // extern JOB_TYPE * global $node; // extern NODE_TYPE * global $devhdr; $k = 0; // int $X = 0.0; // double $devR = 0.0; // double $devD = 0.0; // double $p = "print_node_stats()"; // char * if ($DEBUG) { debug($p, "Entering"); } if (!$devhdr) { print_dev_head(); } getjob_name($s1, $c); switch ($should_be_class) { case TERM: $X = $job[$c]->term->sys->thruput; break; case BATCH: $X = $job[$c]->batch->sys->thruput; break; case TRANS: $X = $job[$c]->trans->arrival_rate; break; default: break; } for ($k = 0; $k < $nodes; $k++) { if ($node[$k]->demand[$c] == 0) { continue; } if ($demand_ext == VISITS) { $s4 = "Visits/" . $tUnit; } else { $s4 = $wUnit . "/" . $tUnit; } printf("%-14s %-10s %-10s %10.4f %-7s\n", "Throughput", $node[$k]->devname, $s1, $demand_ext == VISITS ? $node[$k]->visits[$c] * $X : $X, $s4); /* calculate other stats */ printf("%-14s %-10s %-10s %10.4f %-7s\n", "Utilization", $node[$k]->devname, $s1, $node[$k]->sched == ISRV ? 100 : $node[$k]->demand[$c] * $X * 100, "Percent"); printf("%-14s %-10s %-10s %10.4f %-7s\n", "Queue Length", $node[$k]->devname, $s1, $node[$k]->sched == ISRV ? 0 : $node[$k]->resit[$c] * $X, $wUnit); printf("%-14s %-10s %-10s %10.4f %-7s\n", "Residence Time", $node[$k]->devname, $s1, $node[$k]->sched == ISRV ? $node[$k]->demand[$c] : $node[$k]->resit[$c], $tUnit); if ($demand_ext == VISITS) { /* don't do this if service-time is unspecified */ $devD = $node[$k]->demand[$c]; $devR = $node[$k]->resit[$c]; printf("%-14s %-10s %-10s %10.4f %-7s\n", "Waiting Time", $node[$k]->devname, $s1, $node[$k]->sched == ISRV ? $devD : $devR - $devD, $tUnit); } printf("\n"); } if ($DEBUG) { debug($p, "Exiting"); } }
function PDQ_Solve($meth) { global $DEBUG, $method, $streams, $nodes; // extern int //global $centers_declared, $streams_declared; // extern int global $job; // extern JOB_TYPE * global $node; // extern NODE_TYPE * global $s1, $s2, $s3, $s4; // extern char[] global $sumD; // extern double $k = 0; // int $c = 0; // int $should_be_class = 0; // int $demand = 0.0; // double $maxD = 0.0; // double $p = "PDQ_Solve()"; // char * if ($DEBUG) { debug($p, "Entering"); } /* There'd better be a job[0] or you're in trouble !!! */ $method = $meth; switch ($method) { case EXACT: if ($job[0]->network != CLOSED) { /* bail ! */ typetostr($s2, $job[0]->network); typetostr($s3, $method); $s1 = sprintf("Network should_be_class \"%s\" is incompatible with \"%s\" method", $s2, $s3); errmsg($p, $s1); } switch ($job[0]->should_be_class) { case TERM: case BATCH: exact(); break; default: break; } break; case APPROX: if ($job[0]->network != CLOSED) { /* bail ! */ typetostr($s2, $job[0]->network); typetostr($s3, $method); $s1 = sprintf("Network should_be_class \"%s\" is incompatible with \"%s\" method", $s2, $s3); errmsg($p, $s1); } switch ($job[0]->should_be_class) { case TERM: case BATCH: approx(); break; default: break; } break; case CANON: if ($job[0]->network != OPEN) { /* bail out ! */ typetostr($s2, $job[0]->network); typetostr($s3, $method); $s1 = sprintf("Network should_be_class \"%s\" is incompatible with \"%s\" method", $s2, $s3); errmsg($p, $s1); } canonical(); break; default: typetostr($s3, $method); $s1 = sprintf("Unknown method \"%s\"", $s3); errmsg($p, $s1); break; } /* Now compute bounds */ for ($c = 0; $c < $streams; $c++) { $sumD = 0.0; $maxD = 0.0; $should_be_class = $job[$c]->should_be_class; for ($k = 0; $k < $nodes; $k++) { $demand = $node[$k]->demand[$c]; if ($node[$k]->sched == ISRV && $job[$c]->network == CLOSED) { $demand /= $should_be_class == TERM ? $job[$c]->term->pop : $job[$c]->batch->pop; } if ($maxD < $demand) { $maxD = $demand; } $sumD += $node[$k]->demand[$c]; } /* Over k */ switch ($should_be_class) { case TERM: $job[$c]->term->sys->maxN = ($sumD + $job[$c]->term->think) / $maxD; $job[$c]->term->sys->maxTP = 1.0 / $maxD; $job[$c]->term->sys->minRT = $sumD; if ($sumD == 0) { getjob_name($s1, $c); $s2 = sprintf("Sum of demands is zero for workload \"%s\"", $s1); errmsg($p, $s2); } break; case BATCH: $job[$c]->batch->sys->maxN = $sumD / $maxD; $job[$c]->batch->sys->maxTP = 1.0 / $maxD; $job[$c]->batch->sys->minRT = $sumD; if ($sumD == 0) { getjob_name($s1, $c); $s2 = sprintf("Sum of demands is zero for workload \"%s\"", $s1); errmsg($p, $s2); } break; case TRANS: $job[$c]->trans->sys->maxTP = 1.0 / $maxD; $job[$c]->trans->sys->minRT = $sumD; if ($sumD == 0) { getjob_name($s1, $c); $s2 = sprintf("Sum of demands is zero for workload \"%s\"", $s1); errmsg($p, $s2); } break; default: break; } } /* Over c */ if ($DEBUG) { debug($p, "Exiting"); } }