function create_transaction($net, $label, $lambda) { global $job; // extern JOB_TYPE * global $s1; // extern char[] global $DEBUG; // extern int global $c; $job[$c]->trans->name = $label; $job[$c]->should_be_class = TRANS; $job[$c]->network = $net; $job[$c]->trans->arrival_rate = $lambda; if ($DEBUG) { typetostr($s1, $job[$c]->should_be_class); printf("\tStream[%d]: %s\t\"%s\";\tLambda: %3.1f\n", $c, $s1, $job[$c]->trans->name, $job[$c]->trans->arrival_rate); $s1 = ""; } }
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 print_sys_head() { global $tolerance; // extern double global $s1; // extern char global $DEBUG, $method, $iterations; // extern int global $syshdr; $p = "print_sys_head()"; // char * if ($DEBUG) { debug($p, "Entering"); } printf("\n\n\n\n"); banner_stars(); banner_chars(" PDQ Model OUTPUTS"); banner_stars(); printf("\n\n"); typetostr($s1, $method); printf("Solution Method: %s", $s1); if ($method == APPROX) { printf("\t(Iterations: %d; Accuracy: %3.4lf%%)", $iterations, $tolerance * 100.0); } printf("\n\n"); banner_chars(" SYSTEM Performance"); printf("\n\n"); printf("%-20s\t%10s\t%-10s\n", "Metric", "Value", "Unit"); printf("%-20s\t%10s\t%-10s\n", "-----------------", "-----", "----"); $syshdr = TRUE; 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 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"); } }
function getjob_pop($c) { global $s1, $s2; // extern char[] global $DEBUG, $job; $p = "getjob_pop()"; // char * if ($DEBUG) { debug($p, "Entering"); } switch ($job[$c]->should_be_class) { case TERM: if ($DEBUG) { debug($p, "TERM Exiting"); } return $job[$c]->term->pop; break; case BATCH: if ($DEBUG) { debug($p, "BATCH Exiting"); } return $job[$c]->batch->pop; break; default: /* error */ typetostr($s1, $job[$c]->should_be_class); $s2 = sprintf("Stream %d. Unknown job type %s", $c, $s1); errmsg($p, $s2); break; } return -1.0; }