Alex Bikfalvi
SimStream Documentation
ModelFlow.cpp
00001 #include "Headers.h" 00002 #include "ModelFlow.h" 00003 #include "Shuffle.h" 00004 #include "Rand.h" 00005 #include "Debug.h" 00006 00007 #include "EventFlowConnect.h" 00008 #include "EventFlowDisconnectReceiver.h" 00009 #include "EventFlowDisconnectSender.h" 00010 #include "EventFlowStart.h" 00011 #include "EventFlowStop.h" 00012 00013 #pragma warning(disable : 4996) 00014 00015 CModelFlow::CModelFlow( 00016 __time maxTime, 00017 CTopo* topology, 00018 __uint32 topologyNumber, 00019 __uint32 numHosts, 00020 __uint32 numGateways, 00021 __bitrate bwAccessUpLink, 00022 __bitrate bwAccessDownLink, 00023 __time delayAccessUpLink, 00024 __time delayAccessDownLink, 00025 __uint32 queueLink 00026 ) : CModel(maxTime, topology) 00027 { 00028 assert(numHosts > 0); 00029 assert(numGateways > 0); 00030 00031 // Simulator 00032 this->sim = NULL; 00033 this->topology = topology; 00034 this->topologyNumber = topologyNumber; 00035 00036 // Nodes 00037 this->numHosts = numHosts; 00038 this->numGateways = (numGateways <= this->topology->Nodes())?numGateways:this->topology->Nodes(); 00039 this->bwAccessUpLink = bwAccessUpLink; 00040 this->bwAccessDownLink = bwAccessDownLink; 00041 this->delayAccessUpLink = delayAccessUpLink; 00042 this->delayAccessDownLink = delayAccessDownLink; 00043 this->queueLink = queueLink; 00044 00045 this->hosts = NULL; 00046 this->routers = NULL; 00047 this->linksCore = NULL; 00048 this->linksAccess = NULL; 00049 00050 // Generate gateways 00051 this->gateways = new __uint32[this->numHosts]; 00052 00053 // Generate gateway links (the number of access links for each gateway) 00054 this->routerAccessLinks = new __uint32[this->topology->Nodes()]; 00055 00056 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00057 this->routerAccessLinks[index] = 0; 00058 00059 // Shuffle routers 00060 CShuffle shuffleRouters(this->topology->Nodes()); 00061 00062 // Assign a gateway for each host 00063 for(__uint32 index = 0; index < this->numHosts; index++) 00064 { 00065 __uint32 gw = shuffleRouters[CRand::Generate(this->numGateways-1)]; 00066 assert(gw < this->topology->Nodes()); 00067 00068 this->gateways[index] = gw; 00069 this->routerAccessLinks[gw]++; 00070 } 00071 00072 // Generate route 00073 this->routeNodes = this->topology->Nodes(); 00074 this->routeDst = this->topology->Nodes() + this->numHosts; 00075 00076 this->route = new int*[this->routeNodes]; 00077 00078 for(__uint32 index = 0; index < this->routeNodes; index++) 00079 { 00080 this->route[index] = new int[this->routeDst]; 00081 } 00082 } 00083 00084 CModelFlow::~CModelFlow() 00085 { 00086 // Delete gateways 00087 delete[] this->gateways; 00088 delete[] this->routerAccessLinks; 00089 00090 // Delete routes 00091 for(__uint32 index = 0; index < this->routeNodes; index++) 00092 delete[] this->route[index]; 00093 delete[] this->route; 00094 } 00095 00096 void CModelFlow::Init(CSimHandler* sim) 00097 { 00098 this->sim = sim; 00099 00100 // Generate hosts 00101 this->hosts = new CHostFlow*[this->numHosts]; 00102 00103 for(__uint32 index = 0; index < this->numHosts; index++) 00104 { 00105 this->hosts[index] = new CHostFlow( 00106 HOST_ID(index), 00107 this->sim, 00108 HOST_ADDR(index), 00109 this 00110 ); 00111 } 00112 00113 // Generate routers 00114 this->routers = new CRouter*[this->topology->Nodes()]; 00115 00116 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00117 { 00118 this->routers[index] = new CRouter( 00119 ROUTER_ID(this->topology->Node(index)->Id()), 00120 this->sim, 00121 ROUTER_ADDR(index), 00122 this->topology->Node(index)->Degree() + this->routerAccessLinks[index], 00123 this, 00124 this, 00125 NULL 00126 ); 00127 } 00128 00129 // Generate core links 00130 this->linksCore = new CLink*[this->topology->Edges()]; 00131 00132 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00133 { 00134 assert(this->topology->Edge(index)->Nodes()[0] < this->topology->Nodes()); 00135 assert(this->topology->Edge(index)->Nodes()[1] < this->topology->Nodes()); 00136 00137 this->linksCore[index] = new CLink( 00138 LINK_CORE_ID(this->topology->Edge(index)->Id()), 00139 this->sim, 00140 this->queueLink, 00141 this->topology->Edge(index)->Bandwidth(), 00142 this->topology->Edge(index)->Bandwidth(), 00143 this->topology->Edge(index)->Delay(), 00144 this->topology->Edge(index)->Delay()); 00145 } 00146 00147 // Generate access links 00148 this->linksAccess = new CLink*[this->numHosts]; 00149 00150 for(__uint32 index = 0; index < this->numHosts; index++) 00151 { 00152 this->linksAccess[index] = new CLink( 00153 LINK_ACCESS_ID(index), 00154 this->sim, 00155 this->queueLink, 00156 this->bwAccessUpLink, 00157 this->bwAccessDownLink, 00158 this->delayAccessUpLink, 00159 this->delayAccessDownLink 00160 ); 00161 } 00162 00163 // Generate node-link mappings 00164 // Generate for routers and core links 00165 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00166 for(__uint32 idx = 0; idx < this->topology->Node(index)->Degree(); idx++) 00167 this->routers[index]->AddLink(this->linksCore[this->topology->Node(index)->Edge(idx)]); 00168 00169 // Generate for hosts, gateway routers and access links 00170 for(__uint32 index = 0; index < this->numHosts; index++) 00171 { 00172 // Add link to the host: entry 0 corresponds to the host (uplink) 00173 this->hosts[index]->AddLink(this->linksAccess[index]); 00174 00175 // Add link to the corresponding gateway: entry 1 corresponds to the router (downlink) 00176 this->routers[this->gateways[index]]->AddLink(this->linksAccess[index]); 00177 } 00178 00179 // Calculate routes 00180 for(__uint32 node = 0; node < this->routeNodes; node++) 00181 { 00182 // Routes: node to node 00183 for(__uint32 dst = 0; dst < this->routeNodes; dst++) 00184 if(dst == node) this->route[ROUTER_ADDR(node)][ROUTER_ADDR(dst)] = -1; 00185 else this->route[ROUTER_ADDR(node)][ROUTER_ADDR(dst)] = this->routers[node]->LinkIndex(this->linksCore[this->topology->Route()->NextEdge(node, dst)]->Id()); 00186 00187 // Routes: node to host 00188 for(__uint32 host = 0; host < this->numHosts; host++) 00189 { 00190 if(this->gateways[host] == node) 00191 { 00192 // If the node is the gateway of the destination 00193 this->route[ROUTER_ADDR(node)][HOST_ADDR(host)] = this->routers[node]->LinkIndex(this->linksAccess[host]->Id()); 00194 } 00195 else 00196 { 00197 // Else: the route to the gateway 00198 this->route[ROUTER_ADDR(node)][HOST_ADDR(host)] = this->routers[node]->LinkIndex(this->linksCore[this->topology->Route()->NextEdge(node, this->gateways[host])]->Id()); 00199 } 00200 } 00201 } 00202 00203 00204 #if DEBUG_TOPOLOGY 00205 // Verify routers 00206 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00207 { 00208 // Check the links 00209 for(__uint32 idx = 0; idx < this->routers[index]->NumLinks(); idx++) 00210 { 00211 CLink* link = this->routers[index]->Link(idx); 00212 __uint32 entry = this->routers[index]->LinkEntry(idx); 00213 00214 assert(link); 00215 assert(link->Node(entry) == this->routers[index]); 00216 assert(link->NodeEntry(entry) == idx); 00217 } 00218 } 00219 // Verify hosts 00220 for(__uint32 index = 0; index < this->numHosts; index++) 00221 { 00222 CLink* link = this->hosts[index]->Link(); 00223 __uint32 entry = this->hosts[index]->LinkEntry(); 00224 00225 assert(link); 00226 assert(link->Node(entry) == this->hosts[index]); 00227 assert(link->NodeEntry(entry) == 0); 00228 } 00229 // Verify core links 00230 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00231 { 00232 for(__uint32 idx = 0; idx < 2; idx++) 00233 { 00234 CRouter* router = type_cast<CRouter*>(this->linksCore[index]->Node(idx)); 00235 __uint32 entry = this->linksCore[index]->NodeEntry(idx); 00236 00237 assert(router); 00238 assert(router->Link(entry) == this->linksCore[index]); 00239 assert(router->LinkEntry(entry) == idx); 00240 } 00241 } 00242 // Verify access links 00243 for(__uint32 index = 0; index < this->numHosts; index++) 00244 { 00245 CHost* host = type_cast<CHost*>(this->linksAccess[index]->Node(0)); 00246 __uint32 entryHost = this->linksAccess[index]->NodeEntry(0); 00247 CRouter* router = type_cast<CRouter*>(this->linksAccess[index]->Node(1)); 00248 __uint32 entryRouter = this->linksAccess[index]->NodeEntry(1); 00249 00250 assert(host); 00251 assert(host->Link() == this->linksAccess[index]); 00252 assert(host->LinkEntry() == 0); 00253 assert(router); 00254 assert(router->Link(entryRouter) == this->linksAccess[index]); 00255 assert(router->LinkEntry(entryRouter) == 1); 00256 } 00257 // Verify routes 00258 // router-to-router 00259 00260 for(__uint32 src = 0; src < this->routeNodes; src++) 00261 for(__uint32 dst = 0; dst < this->routeNodes; dst++) 00262 { 00263 CNode* node = this->routers[src]; 00264 CLink* link; 00265 __uint32 linkEntry; 00266 int index; 00267 00268 while(node != this->routers[dst]) 00269 { 00270 index = this->route[node->Address().Address()][this->routers[dst]->Address().Address()]; 00271 link = type_cast<CRouter*>(node)->Link(index); 00272 linkEntry = type_cast<CRouter*>(node)->LinkEntry(index); 00273 node = type_cast<CNode*>(link->Node(linkEntry ^ 1)); 00274 } 00275 // Check the destination was reached 00276 assert(node == this->routers[dst]); 00277 } 00278 00279 // router-to-hosts 00280 for(__uint32 src = 0; src < this->routeNodes; src++) 00281 for(__uint32 dst = 0; dst < this->numHosts; dst++) 00282 { 00283 CNode* node = this->routers[src]; 00284 CLink* link; 00285 __uint32 linkEntry; 00286 int index; 00287 00288 while(node != this->hosts[dst]) 00289 { 00290 index = this->route[node->Address().Address()][this->hosts[dst]->Address().Address()]; 00291 link = type_cast<CRouter*>(node)->Link(index); 00292 linkEntry = type_cast<CRouter*>(node)->LinkEntry(index); 00293 node = type_cast<CNode*>(link->Node(linkEntry ^ 1)); 00294 } 00295 // Check the destination was reached 00296 assert(node == this->hosts[dst]); 00297 } 00298 #endif 00299 } 00300 00301 __uint32 CModelFlow::Events() 00302 { 00303 return 7; //1 + this->numHosts; 00304 } 00305 00306 CSimEvent* CModelFlow::Event(__uint32 index, __time& time) 00307 { 00308 switch(index) 00309 { 00310 case 0: 00311 time = 0; 00312 return new CEventFlowConnect(this->hosts[1], HOST_ADDR(0));; 00313 case 1: 00314 time = 10; 00315 return new CEventFlowStart(this->hosts[0], 0); 00316 case 2: 00317 time = 110; 00318 return new CEventFlowStop(this->hosts[0], 0); 00319 case 3: 00320 time = 900; 00321 //return new CEventFlowDisconnectSender(this->hosts[1]); 00322 return new CEventFlowDisconnectReceiver(this->hosts[1]); 00323 case 4: 00324 time = 50; 00325 return new CEventFlowConnect(this->hosts[2], HOST_ADDR(0));; 00326 case 5: 00327 time = 60; 00328 return new CEventFlowStart(this->hosts[0], 1); 00329 case 6: 00330 time = 160; 00331 return new CEventFlowStop(this->hosts[0], 1); 00332 case 7: 00333 time = 900; 00334 //return new CEventFlowDisconnectSender(this->hosts[1]); 00335 return new CEventFlowDisconnectReceiver(this->hosts[2]); 00336 } 00337 return NULL; 00338 } 00339 00340 void CModelFlow::Finalize() 00341 { 00342 //FILE* out; 00343 //char fileName[1024]; 00344 00345 /* 00346 * Simple statistics 00347 */ 00348 00349 // Calculate data 00350 00351 // Data : bandwidth 00352 this->dataBwTotal = 0; 00353 00354 // Data : bandwidth core 00355 this->dataBwCoreTotal = 0; 00356 00357 // Data : bandwidth access 00358 this->dataBwAccessTotal = 0; 00359 00360 // Data : bandwidth access uplink 00361 this->dataBwAccessUpTotal = 0; 00362 00363 // Data : bandwidth access downlink 00364 this->dataBwAccessDownTotal = 0; 00365 00366 // Data : bandwidth stream 00367 this->dataBwStreamTotal = 0; 00368 00369 // Data : bandwidth core stream 00370 this->dataBwCoreStreamTotal = 0; 00371 00372 // Data : bandwidth access stream 00373 this->dataBwAccessStreamTotal = 0; 00374 00375 // Data : bandwidth access uplink stream 00376 this->dataBwAccessUpStreamTotal = 0; 00377 00378 // Data : bandwidth access downlink stream 00379 this->dataBwAccessDownStreamTotal = 0; 00380 00381 // Data : bandwidth control 00382 this->dataBwControlTotal = 0; 00383 00384 // Data : bandwidth core control 00385 this->dataBwCoreControlTotal = 0; 00386 00387 // Data : bandwidth access control 00388 this->dataBwAccessControlTotal = 0; 00389 00390 // Data : bandwidth access uplink control 00391 this->dataBwAccessUpControlTotal = 0; 00392 00393 // Data : bandwidth access downlink control 00394 this->dataBwAccessDownControlTotal = 0; 00395 00396 // Core links 00397 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00398 { 00399 this->dataBwTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1) + this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00400 this->dataBwCoreTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1) + this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00401 this->dataBwStreamTotal += this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00402 this->dataBwCoreStreamTotal += this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00403 this->dataBwControlTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1); 00404 this->dataBwCoreControlTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1); 00405 } 00406 00407 // Access links 00408 for(__uint32 index = 0; index < this->numHosts; index++) 00409 { 00410 this->dataBwTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00411 this->dataBwAccessTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00412 this->dataBwAccessUpTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(1,0); 00413 this->dataBwAccessDownTotal += this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,1); 00414 this->dataBwStreamTotal += this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00415 this->dataBwAccessStreamTotal += this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00416 this->dataBwAccessUpStreamTotal += this->linksAccess[index]->StatBits(1,0); 00417 this->dataBwAccessDownStreamTotal += this->linksAccess[index]->StatBits(1,1); 00418 this->dataBwControlTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1); 00419 this->dataBwAccessControlTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1); 00420 this->dataBwAccessUpControlTotal += this->linksAccess[index]->StatBits(0,0); 00421 this->dataBwAccessDownControlTotal += this->linksAccess[index]->StatBits(0,1); 00422 } 00423 00424 this->dataBwAvg = this->dataBwTotal/this->maxTime; 00425 this->dataBwCoreAvg = this->dataBwCoreTotal/this->maxTime; 00426 this->dataBwAccessAvg = this->dataBwAccessTotal/this->maxTime; 00427 this->dataBwAccessUpAvg = this->dataBwAccessUpTotal/this->maxTime; 00428 this->dataBwAccessDownAvg = this->dataBwAccessDownTotal/this->maxTime; 00429 this->dataBwStreamAvg = this->dataBwStreamTotal/this->maxTime; 00430 this->dataBwCoreStreamAvg = this->dataBwCoreStreamTotal/this->maxTime; 00431 this->dataBwAccessStreamAvg = this->dataBwAccessStreamTotal/this->maxTime; 00432 this->dataBwAccessUpStreamAvg = this->dataBwAccessUpStreamTotal/this->maxTime; 00433 this->dataBwAccessDownStreamAvg = this->dataBwAccessDownStreamTotal/this->maxTime; 00434 this->dataBwControlAvg = this->dataBwControlTotal/this->maxTime; 00435 this->dataBwCoreControlAvg = this->dataBwCoreControlTotal/this->maxTime; 00436 this->dataBwAccessControlAvg = this->dataBwAccessControlTotal/this->maxTime; 00437 this->dataBwAccessUpControlAvg = this->dataBwAccessUpControlTotal/this->maxTime; 00438 this->dataBwAccessDownControlAvg = this->dataBwAccessDownControlTotal/this->maxTime; 00439 00440 // Routers 00441 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00442 { 00443 this->routers[index]->Finalize(); 00444 } 00445 00447 //sprintf(fileName, "network_%s_%u.out", this->name, this->topologyNumber); 00448 //if(FILE_OPEN(out, fileName, "a")) printf("\nCannot write to file %s.", fileName); 00449 //else 00450 //{ 00451 // fprintf(out, "%u %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %.9lf %.9lf %.9lf\n", 00452 // this->numChannelsMcast, // 1 00453 // this->dataBwTotal, // 2 00454 // this->dataBwAvg, // 3 00455 // this->dataBwCoreTotal, // 4 00456 // this->dataBwCoreAvg, // 5 00457 // this->dataBwAccessTotal, // 6 00458 // this->dataBwAccessAvg, // 7 00459 // this->dataBwAccessUpTotal, // 8 00460 // this->dataBwAccessUpAvg, // 9 00461 // this->dataBwAccessDownTotal, // 10 00462 // this->dataBwAccessDownAvg, // 11 00463 // this->dataBwServerTotal, // 12 00464 // this->dataBwServerAvg, // 13 00465 // this->dataBwStreamTotal, // 14 00466 // this->dataBwStreamAvg, // 15 00467 // this->dataBwCoreStreamTotal, // 16 00468 // this->dataBwCoreStreamAvg, // 17 00469 // this->dataBwAccessStreamTotal, // 18 00470 // this->dataBwAccessStreamAvg, // 19 00471 // this->dataBwAccessUpStreamTotal, // 20 00472 // this->dataBwAccessUpStreamAvg, // 21 00473 // this->dataBwAccessDownStreamTotal, // 22 00474 // this->dataBwAccessDownStreamAvg, // 23 00475 // this->dataBwServerStreamTotal, // 24 00476 // this->dataBwServerStreamAvg, // 25 00477 // this->dataBwControlTotal, // 26 00478 // this->dataBwControlAvg, // 27 00479 // this->dataBwCoreControlTotal, // 28 00480 // this->dataBwCoreControlAvg, // 29 00481 // this->dataBwAccessControlTotal, // 30 00482 // this->dataBwAccessControlAvg, // 31 00483 // this->dataBwAccessUpControlTotal, // 32 00484 // this->dataBwAccessUpControlAvg, // 33 00485 // this->dataBwAccessDownControlTotal, // 34 00486 // this->dataBwAccessDownControlAvg, // 35 00487 // this->dataBwServerControlTotal, // 36 00488 // this->dataBwServerControlAvg, // 37 00489 // this->dataRouterMcastEntries, // 38 00490 // this->dataRouterMcastEntriesIgmp, // 39 00491 // this->dataRouterMcastEntriesPimSm // 40 00492 // ); 00493 00494 // fclose(out); 00495 //} 00496 00497 /* 00498 * Cleanup objects created during simulation (objects that cannot be deleted in the destructor because they depend on the simulator) 00499 */ 00500 00501 // Delete hosts 00502 if(this->hosts) 00503 { 00504 for(__uint32 index = 0; index < this->numHosts; index++) 00505 delete this->hosts[index]; 00506 delete[] this->hosts; 00507 } 00508 00509 // Delete routers 00510 if(this->routers) 00511 { 00512 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00513 delete this->routers[index]; 00514 delete[] this->routers; 00515 } 00516 00517 // Delete links core 00518 if(this->linksCore) 00519 { 00520 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00521 delete this->linksCore[index]; 00522 delete[] this->linksCore; 00523 } 00524 00525 // Delete links access 00526 if(this->linksAccess) 00527 { 00528 for(__uint32 index = 0; index < this->numHosts; index++) 00529 delete this->linksAccess[index]; 00530 delete[] this->linksAccess; 00531 } 00532 } 00533 00534 int CModelFlow::Forward(CAddress node, CAddress dst) 00535 { 00536 // Calculates the outgoing link when the router receives a packet with a certain destination 00537 assert(node.Address() <= this->routeNodes); 00538 assert(dst.Address() <= this->routeDst); 00539 00540 return this->route[node.Address()][dst.Address()]; 00541 } 00542 00543 00544 #ifdef MULTICAST 00545 00546 void CModelFlow::MulticastJoin(__uint32 host, __uint32 group) 00547 { 00548 // Add host to multicast group 00549 (*this->multicast)[group]->Add(this->sim->Time(), HOST_INDEX(host), this->gateways[HOST_INDEX(host)]); 00550 } 00551 00552 void CModelFlow::MulticastLeave(__uint32 host, __uint32 group) 00553 { 00554 // Remove host from multicast group 00555 (*this->multicast)[group]->Remove(this->sim->Time(), HOST_INDEX(host), this->gateways[HOST_INDEX(host)]); 00556 } 00557 00558 #endif
Last updated: February 8, 2011