double PDQ_GetQueueLength(char *device, char *work, int should_be_class) { char *p = "PDQ_GetQueueLength()"; extern char s1[]; // Initialize vars to suppress compiler warnings double q = 0.0; double x = 0.0; int c = 0; int k = 0; // Added by NJG on Wednesday, August 19, 2015 if (!streams) PRINTF("PDQ_GetQueueLength warning: No PDQ workload defined.\n"); if (!nodes) PRINTF("PDQ_GetQueueLength warning: No PDQ nodes defined.\n"); if (!demands) PRINTF("PDQ_GetQueueLength warning: No PDQ service demands defined.\n"); c = getjob_index(work); x = PDQ_GetThruput(should_be_class, work); for (k = 0; k < nodes; k++) { if (strcmp(device, node[k].devname) == 0) { q = node[k].resit[c] * x; return (q); } } sprintf(s1, "Unknown device %s", device); errmsg(p, s1); g_debug("PDQ_GetQueueLength - Bad double return"); return -1.0; } /* PDQ_GetQueueLength */
double PDQ_GetQueueLength(char *device, char *work, int should_be_class) { char *p = "PDQ_GetQueueLength()"; extern char s1[]; double q, x; int c, k; c = getjob_index(work); x = PDQ_GetThruput(should_be_class, work); for (k = 0; k < nodes; k++) { if (strcmp(device, node[k].devname) == 0) { q = node[k].resit[c] * x; return (q); } } sprintf(s1, "Unknown device %s", device); errmsg(p, s1); g_debug("PDQ_GetQueueLength - Bad double return"); return -1.0; } /* PDQ_GetQueueLength */
void mem_model(int n, int m) { extern double GetThruput(); float x = 0.0; int i; int noNodes; int noStreams; for (i = 1; i <= n; i++) { if (i <= m) { PDQ_Init(""); noNodes = PDQ_CreateNode("CPU", CEN, FCFS); noNodes = PDQ_CreateNode("DK1", CEN, FCFS); noNodes = PDQ_CreateNode("DK2", CEN, FCFS); noStreams = PDQ_CreateClosed("work", TERM, (float) i, 0.0); PDQ_SetDemand("CPU", "work", 3.0); PDQ_SetDemand("DK1", "work", 4.0); PDQ_SetDemand("DK2", "work", 2.0); PDQ_Solve(EXACT); x = PDQ_GetThruput(TERM, "work"); sm_x[i] = x; } else sm_x[i] = x; /* last computed value */ } } /* mem_model */
void multiserver(int m, double stime) { int i; int nodes; int streams; double x; char *work = "reqs"; char *node = "bus"; for (i = 1; i <= CPUS; i++) { //fprintf(stderr, "[multiserver] i -> %d, m -> %d, stime -> %f\n", i, m, stime); if (i <= m) { PDQ_Init("multibus"); streams = PDQ_CreateClosed(work, TERM, (double) i, 0.0); nodes = PDQ_CreateNode(node, CEN, ISRV); PDQ_SetDemand(node, work, stime); PDQ_Solve(EXACT); x = PDQ_GetThruput(TERM, work); sm_x[i] = x; } else { sm_x[i] = x; } } } /* multiserver */
double PDQ_GetUtilization(char *device, char *work, int should_be_class) { char *p = "PDQ_GetUtilization()"; extern char s1[]; // Initialize vars to suppress compiler warnings double x = 0.0; double u = 0.0; int c = 0; int k = 0; int m = 0; // Added by NJG on Wednesday, August 19, 2015 if (!streams) PRINTF("PDQ_GetUtilization warning: No PDQ workload defined.\n"); if (!nodes) PRINTF("PDQ_GetUtilization warning: No PDQ nodes defined.\n"); if (!demands) PRINTF("PDQ_GetUtilization warning: No PDQ service demands defined.\n"); // g_debug("PDQ_GetUtilization\n"); // g_debugf("job[%d]\n", job); // g_debugf("work[%s]\n", work); // g_debugf("class[%d]\n", should_be_class); if (job) { // g_debugf("work[%s]\n", work); c = getjob_index(work); x = PDQ_GetThruput(should_be_class, work); for (k = 0; k < nodes; k++) { if (strcmp(device, node[k].devname) == 0) { // X is total arrival rate for MSQ u = node[k].demand[c] * x; // Updated by NJG on Dec 29, 2018 with new NODE_TYPEs in PDQ_Lib.h // Edited by NJG on September 10, 2009 // Divide by m to calculate per-server utilization if (node[k].devtype == MSO) { m = node[k].servers; u = u / m; } return (u); } } sprintf(s1, "Unknown device %s", device); errmsg(p, s1); } g_debug("PDQ_GetUtiliation: Failed to find utilization\n"); /* # b. why is there no return value? */ return 0.0; } /* PDQ_GetUtilization */
double PDQ_GetUtilization(char *device, char *work, int should_be_class) { char *p = "PDQ_GetUtilization()"; extern char s1[]; double x, u; int c, k, m; // g_debug("PDQ_GetUtilization\n"); // g_debugf("job[%d]\n", job); // g_debugf("work[%s]\n", work); // g_debugf("class[%d]\n", should_be_class); if (job) { // g_debugf("work[%s]\n", work); c = getjob_index(work); x = PDQ_GetThruput(should_be_class, work); for (k = 0; k < nodes; k++) { if (strcmp(device, node[k].devname) == 0) { // X is total arrival rate for MSQ u = node[k].demand[c] * x; // Edited by NJG on Thursday, September 10, 2009 // Calculate per-server utilization; divide by m if (node[k].sched == MSQ) { m = node[k].devtype; u = u/m; } return (u); } } sprintf(s1, "Unknown device %s", device); errmsg(p, s1); } g_debug("PDQ_GetUtiliation: Failed to find utilization\n"); /* # b. why is there no return value? */ return 0.0; } /* PDQ_GetUtilization */
int main() { extern JOB_TYPE *job; extern double getjob_pop(); extern int getjob_index(); extern double PDQ_GetResponse(); extern double PDQ_GetThruput(); extern double PDQ_GetUtilization(); /**************************** * Model specific variables * ****************************/ int noNodes; int noStreams; int pop, servers = 2; int s, w; #define STRESS 0 #define HOMEPG 1 static char *work[] = { "stress", "homepg" }; static double time[] = { 0.0044, /* stress */ 0.0300 /* homepg */ }; static char *slave[] = { "slave0", "slave1", "slave2", "slave3", "slave4", "slave5", "slave6", "slave7", "slave8", "slave9", "slave10", "slave11", "slave12", "slave13", "slave14", "slave15" }; #define PREFORK w = HOMEPG; #ifdef PREFORK printf("Pre-Fork Model under \"%s\" Load (m = %d)\n", w == STRESS ? work[STRESS] : work[HOMEPG], servers); #else printf("Forking Model under \"%s\" Load \n", w == STRESS ? work[STRESS] : work[HOMEPG]); #endif printf("\n N X R\n"); for (pop = 1; pop <= 10; pop++) { PDQ_Init("HTTPd_Server"); noStreams = PDQ_CreateClosed(work[w], TERM, 1.0 * pop, 0.0); noNodes = PDQ_CreateNode("master", CEN, FCFS); #ifdef PREFORK for (s = 0; s < servers; s++) { noNodes = PDQ_CreateNode(slave[s], CEN, FCFS); } PDQ_SetDemand("master", work[w], 0.0109); for (s = 0; s < servers; s++) { PDQ_SetDemand(slave[s], work[w], time[w] / servers); } #else /* FORKING */ noNodes = PDQ_CreateNode("forks", CEN, ISRV); PDQ_SetDemand("master", work[w], 0.0165); PDQ_SetDemand("forks", work[w], time[w]); #endif PDQ_Solve(EXACT); printf("%5.2f %8.4f %8.4f\n", getjob_pop(getjob_index(work[w])), PDQ_GetThruput(TERM, work[w]), PDQ_GetResponse(TERM, work[w])); } return(0); } // main
int main() { void namex(); int intwt(); void itoa(); char cname[10]; /* cache id */ char wname[10]; /* workload */ int i; /* per CPU intruction stream intensity */ double Prhit = (RD * HT); double Pwhit = (WR * HT * (1 - WUMD)) + (WR * (1 - HT) * (1 - MD)); double Prdop = RD * (1 - HT); double Pwbop = WR * (1 - HT) * MD; double Pwthr = WR; double Pinvl = WR * HT * WUMD; double Nrwht = 0.8075 * MAXCPU; double Nrdop = 0.0850 * MAXCPU; double Nwthr = 0.15 * MAXCPU; double Nwbop = 0.0003 * MAXCPU * 100; double Ninvl = 0.015 * MAXCPU; double Srdop = (20.0); double Swthr = (25.0); double Swbop = (20.0); double Wrwht; double Wrdop; double Wwthr; double Wwbop; double Winvl; double Zrwht = ZX; double Zrdop = ZX; double Zwbop = ZX; double Zinvl = ZX; double Zwthr = ZX; double Xcpu = 0.0; double Pcpu = 0.0; double Ubrd = 0.0; double Ubwr = 0.0; double Ubin = 0.0; double Ucht = 0.0; double Ucrd = 0.0; double Ucwr = 0.0; double Ucin = 0.0; char *model = "ABC Model"; PDQ_Init(model); /* create single bus queueing center */ PDQ_CreateNode(BUS, CEN, FCFS); /* create per CPU cache queueing centers */ for (i = 0; i < MAXCPU; i++) { namex(i, L2C, cname); PDQ_CreateNode(cname, CEN, FCFS); } /* create CPU nodes, workloads, and demands */ for (i = 0; i < intwt(Nrwht, &Wrwht); i++) { namex(i, RWHT, wname); PDQ_CreateClosed(wname, TERM, Nrwht, Zrwht); namex(i, L2C, cname); PDQ_SetDemand(cname, wname, 1.0); PDQ_SetDemand(BUS, wname, 0.0); /* no bus activity */ } for (i = 0; i < intwt(Nrdop, &Wrdop); i++) { namex(i, RDOP, wname); PDQ_CreateClosed(wname, TERM, Nrdop, Zrdop); namex(i, L2C, cname); PDQ_SetDemand(cname, wname, gen); /* generate bus request */ PDQ_SetDemand(BUS, wname, Srdop); /* req + async data return */ } if (WBACK) { for (i = 0; i < intwt(Nwbop, &Wwbop); i++) { namex(i, WROP, wname); PDQ_CreateClosed(wname, TERM, Nwbop, Zwbop); namex(i, L2C, cname); PDQ_SetDemand(cname, wname, gen); PDQ_SetDemand(BUS, wname, Swbop); /* asych write to memory ? */ } } else { /* write-thru */ for (i = 0; i < intwt(Nwthr, &Wwthr); i++) { namex(i, WROP, wname); PDQ_CreateClosed(wname, TERM, Nwthr, Zwthr); namex(i, L2C, cname); PDQ_SetDemand(cname, wname, gen); PDQ_SetDemand(BUS, wname, Swthr); } } if (WBACK) { for (i = 0; i < intwt(Ninvl, &Winvl); i++) { namex(i, INVL, wname); PDQ_CreateClosed(wname, TERM, Ninvl, Zinvl); namex(i, L2C, cname); PDQ_SetDemand(cname, wname, gen); /* gen + intervene */ PDQ_SetDemand(BUS, wname, 1.0); } } PDQ_SetWUnit("Reqs"); PDQ_SetTUnit("Cycs"); PDQ_Solve(APPROX); /* bus utilizations */ for (i = 0; i < intwt(Nrdop, &Wrdop); i++) { namex(i, RDOP, wname); Ubrd += PDQ_GetUtilization(BUS, wname, TERM); } Ubrd *= Wrdop; if (WBACK) { for (i = 0; i < intwt(Nwbop, &Wwbop); i++) { namex(i, WROP, wname); Ubwr += PDQ_GetUtilization(BUS, wname, TERM); } Ubwr *= Wwbop; for (i = 0; i < intwt(Ninvl, &Winvl); i++) { namex(i, INVL, wname); Ubin += PDQ_GetUtilization(BUS, wname, TERM); } Ubin *= Winvl; } else { /* write-thru */ for (i = 0; i < intwt(Nwthr, &Wwthr); i++) { namex(i, WROP, wname); Ubwr += PDQ_GetUtilization(BUS, wname, TERM); } Ubwr *= Wwthr; } /* cache measures at CPU[0] only */ i = 0; namex(i, L2C, cname); namex(i, RWHT, wname); Xcpu = PDQ_GetThruput(TERM, wname) * Wrwht; Pcpu += Xcpu * Zrwht; Ucht = PDQ_GetUtilization(cname, wname, TERM) * Wrwht; namex(i, RDOP, wname); Xcpu = PDQ_GetThruput(TERM, wname) * Wrdop; Pcpu += Xcpu * Zrdop; Ucrd = PDQ_GetUtilization(cname, wname, TERM) * Wrdop; Pcpu *= 1.88; if (WBACK) { namex(i, WROP, wname); Ucwr = PDQ_GetUtilization(cname, wname, TERM) * Wwbop; namex(i, INVL, wname); Ucin = PDQ_GetUtilization(cname, wname, TERM) * Winvl; } else { /* write-thru */ namex(i, WROP, wname); Ucwr = PDQ_GetUtilization(cname, wname, TERM) * Wwthr; } printf("\n**** %s Results ****\n", model); printf("PDQ nodes: %d PDQ streams: %d\n", PDQ_GetNodesCount(), PDQ_GetStreamsCount()); printf("Memory Mode: %s\n", WBACK ? "WriteBack" : "WriteThru"); printf("Ncpu: %2d\n", MAXCPU); printf("Nrwht: %5.2f (N:%2d W:%5.2f)\n", Nrwht, intwt(Nrwht, &Wrwht), Wrwht); printf("Nrdop: %5.2f (N:%2d W:%5.2f)\n", Nrdop, intwt(Nrdop, &Wrdop), Wrdop); if (WBACK) { printf("Nwbop: %5.2f (N:%2d W:%5.2f)\n", Nwbop, intwt(Nwbop, &Wwbop), Wwbop); printf("Ninvl: %5.2f (N:%2d W:%5.2f)\n", Ninvl, intwt(Ninvl, &Winvl), Winvl); } else { printf("Nwthr: %5.2f (N:%2d W:%5.2f)\n", Nwthr, intwt(Nwthr, &Wwthr), Wwthr); } printf("\n"); printf("Hit Ratio: %5.2f %%\n", HT * 100.0); printf("Read Miss: %5.2f %%\n", RD * (1 - HT) * 100.0); printf("WriteMiss: %5.2f %%\n", WR * (1 - HT) * 100.0); printf("Ucpu: %5.2f %%\n", Pcpu * 100.0 / MAXCPU); printf("Pcpu: %5.2f\n", Pcpu); printf("\n"); printf("Ubus[reads]: %5.2f %%\n", Ubrd * 100.0); printf("Ubus[write]: %5.2f %%\n", Ubwr * 100.0); printf("Ubus[inval]: %5.2f %%\n", Ubin * 100.0); printf("Ubus[total]: %5.2f %%\n", (Ubrd + Ubwr + Ubin) * 100.0); printf("\n"); printf("Uca%d[hits]: %5.2f %%\n", i, Ucht * 100.0); printf("Uca%d[reads]: %5.2f %%\n", i, Ucrd * 100.0); printf("Uca%d[write]: %5.2f %%\n", i, Ucwr * 100.0); printf("Uca%d[inval]: %5.2f %%\n", i, Ucin * 100.0); printf("Uca%d[total]: %5.2f %%\n", i, (Ucht + Ucrd + Ucwr + Ucin) * 100.0); }