int main(int argc, char **argv) { EventList eventlist; eventlist.setEndtime(timeFromSec(5000)); Clock c(timeFromSec(50/100.), eventlist); int algo = UNCOUPLED; double epsilon = 1; int crt = 2; if (argc>1) { if (!strcmp(argv[1],"UNCOUPLED")) algo = UNCOUPLED; else if (!strcmp(argv[1],"COUPLED_INC")) algo = COUPLED_INC; else if (!strcmp(argv[1],"FULLY_COUPLED")) algo = FULLY_COUPLED; else if (!strcmp(argv[1],"COUPLED_TCP")) algo = COUPLED_TCP; else if (!strcmp(argv[1],"COUPLED_EPSILON")) { algo = COUPLED_EPSILON; if (argc>2) { epsilon = atof(argv[2]); crt++; printf("Using epsilon %f\n",epsilon); } } else exit_error(argv[0]); } linkspeed_bps SERVICE1 = speedFromPktps(400); linkspeed_bps SERVICE2; if (argc>crt) SERVICE2 = speedFromPktps(atoi(argv[crt++])); else SERVICE2 = speedFromPktps(400); simtime_picosec RTT1=timeFromMs(100); simtime_picosec RTT2; if (argc>crt) RTT2 = timeFromMs(atoi(argv[crt])); else RTT2 = timeFromMs(100); mem_b BUFFER1=memFromPkt(RANDOM_BUFFER+timeAsSec(RTT1)*speedAsPktps(SERVICE1));//NUMFLOWS * targetwnd); mem_b BUFFER2=memFromPkt(RANDOM_BUFFER+timeAsSec(RTT2)*speedAsPktps(SERVICE2));//NUMFLOWS * targetwnd); srand(time(NULL)); // prepare the loggers stringstream filename(ios_base::out); filename << "../data/logout." << speedAsPktps(SERVICE2) << "pktps." <<timeAsMs(RTT2) << "ms."<< rand(); cout << "Outputting to " << filename.str() << endl; Logfile logfile(filename.str(),eventlist); logfile.setStartTime(timeFromSec(0.5)); QueueLoggerSimple logQueue = QueueLoggerSimple(); logfile.addLogger(logQueue); // QueueLoggerSimple logPQueue1 = QueueLoggerSimple(); logfile.addLogger(logPQueue1); //QueueLoggerSimple logPQueue3 = QueueLoggerSimple(); logfile.addLogger(logPQueue3); QueueLoggerSimple logPQueue = QueueLoggerSimple(); logfile.addLogger(logPQueue); MultipathTcpLoggerSimple mlogger = MultipathTcpLoggerSimple(); logfile.addLogger(mlogger); //TrafficLoggerSimple logger; //logfile.addLogger(logger); SinkLoggerSampling sinkLogger = SinkLoggerSampling(timeFromMs(1000),eventlist); logfile.addLogger(sinkLogger); QueueLoggerSampling qs1 = QueueLoggerSampling(timeFromMs(1000),eventlist); logfile.addLogger(qs1); QueueLoggerSampling qs2 = QueueLoggerSampling(timeFromMs(1000),eventlist); logfile.addLogger(qs2); TcpLoggerSimple* logTcp = NULL; logTcp = new TcpLoggerSimple(); logfile.addLogger(*logTcp); // Build the network Pipe pipe1(RTT1, eventlist); pipe1.setName("pipe1"); logfile.writeName(pipe1); Pipe pipe2(RTT2, eventlist); pipe2.setName("pipe2"); logfile.writeName(pipe2); Pipe pipe_back(timeFromMs(.1), eventlist); pipe_back.setName("pipe_back"); logfile.writeName(pipe_back); RandomQueue queue1(SERVICE1, BUFFER1, eventlist,&qs1,memFromPkt(RANDOM_BUFFER)); queue1.setName("Queue1"); logfile.writeName(queue1); RandomQueue queue2(SERVICE2, BUFFER2, eventlist,&qs2,memFromPkt(RANDOM_BUFFER)); queue2.setName("Queue2"); logfile.writeName(queue2); Queue pqueue2(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL); pqueue2.setName("PQueue2"); logfile.writeName(pqueue2); Queue pqueue3(SERVICE1*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL); pqueue3.setName("PQueue3"); logfile.writeName(pqueue3); Queue pqueue4(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL); pqueue4.setName("PQueue4"); logfile.writeName(pqueue4); Queue* pqueue; Queue queue_back(max(SERVICE1,SERVICE2)*4, memFromPkt(1000), eventlist,NULL); queue_back.setName("queue_back"); logfile.writeName(queue_back); TcpRtxTimerScanner tcpRtxScanner(timeFromMs(10), eventlist); //TCP flows on path 1 TcpSrc* tcpSrc; TcpSink* tcpSnk; route_t* routeout; route_t* routein; double extrastarttime; for (int i=0; i<TCP_1; i++) { tcpSrc = new TcpSrc(NULL,NULL,eventlist); tcpSrc->setName("Tcp1"); logfile.writeName(*tcpSrc); tcpSnk = new TcpSink(); tcpSnk->setName("Tcp1"); logfile.writeName(*tcpSnk); tcpRtxScanner.registerTcp(*tcpSrc); // tell it the route pqueue = new Queue(SERVICE1*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL); pqueue->setName("PQueue1_"+ntoa(i)); logfile.writeName(*pqueue); routeout = new route_t(); routeout->push_back(pqueue); routeout->push_back(&queue1); routeout->push_back(&pipe1); routeout->push_back(tcpSnk); routein = new route_t(); routein->push_back(tcpSrc); extrastarttime = drand()*50; tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime)); sinkLogger.monitorSink(tcpSnk); } //TCP flow on path 2 for (int i=0; i<TCP_2; i++) { tcpSrc = new TcpSrc(NULL,NULL,eventlist); tcpSrc->setName("Tcp2"); logfile.writeName(*tcpSrc); tcpSnk = new TcpSink(); tcpSnk->setName("Tcp2"); logfile.writeName(*tcpSnk); tcpRtxScanner.registerTcp(*tcpSrc); pqueue = new Queue(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL); pqueue->setName("PQueue2_"+ntoa(i)); logfile.writeName(*pqueue); // tell it the route routeout = new route_t(); routeout->push_back(pqueue); routeout->push_back(&queue2); routeout->push_back(&pipe2); routeout->push_back(tcpSnk); routein = new route_t(); //routein->push_back(&queue_back); routein->push_back(&pipe_back); routein->push_back(tcpSrc); extrastarttime = 50*drand(); tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime)); sinkLogger.monitorSink(tcpSnk); } MultipathTcpSrc* mtcp; if (algo==COUPLED_EPSILON) mtcp = new MultipathTcpSrc(algo,eventlist,&mlogger,epsilon); else mtcp = new MultipathTcpSrc(algo,eventlist,&mlogger); //MTCP flow 1 tcpSrc = new TcpSrc(NULL,NULL,eventlist); tcpSrc->setName("Subflow1"); logfile.writeName(*tcpSrc); tcpSnk = new TcpSink(); tcpSnk->setName("Subflow1"); logfile.writeName(*tcpSnk); tcpRtxScanner.registerTcp(*tcpSrc); // tell it the route routeout = new route_t(); routeout->push_back(&pqueue3); routeout->push_back(&queue1); routeout->push_back(&pipe1); routeout->push_back(tcpSnk); routein = new route_t(); //routein->push_back(&queue_back); routein->push_back(&pipe_back); routein->push_back(tcpSrc); extrastarttime = 50*drand(); //join multipath connection mtcp->addSubflow(tcpSrc); tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime)); sinkLogger.monitorSink(tcpSnk); //MTCP flow 2 tcpSrc = new TcpSrc(NULL,NULL,eventlist); tcpSrc->setName("Subflow2"); logfile.writeName(*tcpSrc); tcpSnk = new TcpSink(); tcpSnk->setName("Subflow2"); logfile.writeName(*tcpSnk); tcpRtxScanner.registerTcp(*tcpSrc); // tell it the route routeout = new route_t(); routeout->push_back(&pqueue4); routeout->push_back(&queue2); routeout->push_back(&pipe2); routeout->push_back(tcpSnk); routein = new route_t(); //routein->push_back(&queue_back); routein->push_back(&pipe_back); routein->push_back(tcpSrc); extrastarttime = 50*drand(); //join multipath connection mtcp->addSubflow(tcpSrc); tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime)); sinkLogger.monitorSink(tcpSnk); // Record the setup int pktsize = TcpPacket::DEFAULTDATASIZE; logfile.write("# pktsize="+ntoa(pktsize)+" bytes"); logfile.write("# bottleneckrate1="+ntoa(speedAsPktps(SERVICE1))+" pkt/sec"); logfile.write("# bottleneckrate2="+ntoa(speedAsPktps(SERVICE2))+" pkt/sec"); logfile.write("# buffer1="+ntoa((double)(queue1._maxsize)/((double)pktsize))+" pkt"); logfile.write("# buffer2="+ntoa((double)(queue2._maxsize)/((double)pktsize))+" pkt"); double rtt = timeAsSec(RTT1); logfile.write("# rtt="+ntoa(rtt)); rtt = timeAsSec(RTT2); logfile.write("# rtt="+ntoa(rtt)); logfile.write("# numflows="+ntoa(NUMFLOWS)); logfile.write("# targetwnd="+ntoa(targetwnd)); // GO! while (eventlist.doNextEvent()) {} }
int main (int argc, char **argv) { eventlist.setEndtime (timeFromSec (200)); Clock c (timeFromSec (50 / 100.), eventlist); int algo = COUPLED_EPSILON; double epsilon = 1; int param = 0; stringstream filename (ios_base::out); uint64_t pktperflow = 1048576LL/1000 + 1; if (argc > 1) { int i = 1; if (!strcmp (argv[1], "-o")) { filename << argv[2]; i += 2; } else { filename << "logout.dat"; } if (argc > i && !strcmp (argv[i], "-sub")) { subflow_count = atoi (argv[i + 1]); i += 2; } if (argc > i && !strcmp (argv[i], "-flowM")) { pktperflow = atoi (argv[i + 1])*1048576LL/1000; i += 2; cout << "Using subflow count " << subflow_count << endl; } if (argc > i && !strcmp (argv[i], "-param")) { param = atoi (argv[i + 1]); i += 2; cout << "Using subflow count " << subflow_count << endl; } if (argc > i) { epsilon = -1; if (!strcmp (argv[i], "UNCOUPLED")) { algo = UNCOUPLED; } else if (!strcmp (argv[i], "COUPLED_INC")) { algo = COUPLED_INC; } else if (!strcmp (argv[i], "FULLY_COUPLED")) { algo = FULLY_COUPLED; } else if (!strcmp (argv[i], "COUPLED_TCP")) { algo = COUPLED_TCP; } else if (!strcmp (argv[i], "COUPLED_SCALABLE_TCP")) { algo = COUPLED_SCALABLE_TCP; } else if (!strcmp (argv[i], "COUPLED_EPSILON")) { algo = COUPLED_EPSILON; if (argc > i + 1) { epsilon = atof (argv[i + 1]); } printf ("Using epsilon %f\n", epsilon); } else { exit_error (argv[0]); } } } srand (time (NULL)); cout << "Using algo=" << algo << " epsilon=" << epsilon << endl; // prepare the loggers cout << "Logging to " << filename.str () << endl; //Logfile Logfile logfile (filename.str (), eventlist); #if PRINT_PATHS filename << ".paths"; cout << "Logging path choices to " << filename.str () << endl; std::ofstream paths (filename.str ().c_str ()); if (!paths) { cout << "Can't open for writing paths file!" << endl; exit (1); } #endif int tot_subs = 0; int cnt_con = 0; lg = &logfile; logfile.setStartTime (timeFromSec (0)); SinkLoggerSampling sinkLogger = SinkLoggerSampling (timeFromMs (1000), eventlist); logfile.addLogger (sinkLogger); //TcpLoggerSimple logTcp;logfile.addLogger(logTcp); TcpSrc *tcpSrc; TcpSink *tcpSnk; //CbrSrc* cbrSrc; //CbrSink* cbrSnk; route_t *routeout, *routein; double extrastarttime; TcpRtxTimerScanner tcpRtxScanner (timeFromMs (10), eventlist); MultipathTcpSrc *mtcp; vector<MultipathTcpSrc*> mptcpVector; int dest; #if USE_FIRST_FIT if (subflow_count == 1) { ff = new FirstFit (timeFromMs (FIRST_FIT_INTERVAL), eventlist); } #endif #ifdef FAT_TREE FatTreeTopology *top = new FatTreeTopology (&logfile, &eventlist, ff); #endif #ifdef OV_FAT_TREE OversubscribedFatTreeTopology *top = new OversubscribedFatTreeTopology (&logfile, &eventlist, ff); #endif #ifdef MH_FAT_TREE MultihomedFatTreeTopology *top = new MultihomedFatTreeTopology (&logfile, &eventlist, ff); #endif #ifdef STAR StarTopology *top = new StarTopology (&logfile, &eventlist, ff); #endif #ifdef BCUBE BCubeTopology *top = new BCubeTopology (&logfile, &eventlist, ff); cout << "BCUBE " << K << endl; #endif #ifdef VL2 VL2Topology *top = new VL2Topology (&logfile, &eventlist, ff); #endif vector < route_t * >***net_paths; net_paths = new vector < route_t * >**[N]; int *is_dest = new int[N]; for (int i = 0; i < N; i++) { is_dest[i] = 0; net_paths[i] = new vector < route_t * >*[N]; for (int j = 0; j < N; j++) { net_paths[i][j] = NULL; } } if (ff) { ff->net_paths = net_paths; } vector < int >*destinations; // Permutation connections ConnectionMatrix *conns = new ConnectionMatrix (N); //conns->setLocalTraffic(top); //cout << "Running perm with " << param << " connections" << endl; //conns->setPermutation(param); //conns->setStaggeredPermutation(top,(double)param/100.0); //conns->setStaggeredRandom(top,512,1); // conns->setHotspot(param,512/param); conns->setStride (3,0); //conns->setManytoMany(128); //conns->setVL2(); //conns->setRandom(param); map < int, vector < int >*>::iterator it; int connID = 0; for (it = conns->connections.begin (); it != conns->connections.end (); it++) { int src = (*it).first; destinations = (vector < int >*) (*it).second; vector < int >subflows_chosen; for (unsigned int dst_id = 0; dst_id < destinations->size (); dst_id++) { connID++; dest = destinations->at (dst_id); if (!net_paths[src][dest]) { net_paths[src][dest] = top->get_paths (src, dest); } /*bool cbr = 1; if (cbr){ cbrSrc = new CbrSrc(eventlist,speedFromPktps(7999),timeFromMs(0),timeFromMs(0)); cbrSnk = new CbrSink(); cbrSrc->setName("cbr_" + ntoa(src) + "_" + ntoa(dest)+"_"+ntoa(dst_id)); logfile.writeName(*cbrSrc); cbrSnk->setName("cbr_sink_" + ntoa(src) + "_" + ntoa(dest)+"_"+ntoa(dst_id)); logfile.writeName(*cbrSnk); // tell it the route if (net_paths[src][dest]->size()==1){ choice = 0; } else { choice = rand()%net_paths[src][dest]->size(); } routeout = new route_t(*(net_paths[src][dest]->at(choice))); routeout->push_back(cbrSnk); cbrSrc->connect(*routeout, *cbrSnk, timeFromMs(0)); } */ { //we should create multiple connections. How many? //if (connID%3!=0) //continue; for (int connection = 0; connection < 1; connection++) { if (algo == COUPLED_EPSILON) { mtcp = new MultipathTcpSrc (algo, eventlist, NULL, epsilon); } else { mtcp = new MultipathTcpSrc (algo, eventlist, NULL); } mptcpVector.push_back(mtcp); //uint64_t bb = generateFlowSize(); // if (subflow_control) //subflow_control->add_flow(src,dest,mtcp); subflows_chosen.clear (); int it_sub; int crt_subflow_count = subflow_count; tot_subs += crt_subflow_count; cnt_con++; it_sub = crt_subflow_count > net_paths[src][dest]-> size ()? net_paths[src][dest]->size () : crt_subflow_count; int use_all = it_sub == net_paths[src][dest]->size (); //if (connID%10!=0) //it_sub = 1; uint64_t pktpersubflow = pktperflow / it_sub; for (int inter = 0; inter < it_sub; inter++) { // if (connID%10==0){ tcpSrc = new TcpSrc (NULL, NULL, eventlist); tcpSrc->set_max_packets(pktpersubflow); tcpSnk = new TcpSink (); /*} else { tcpSrc = new TcpSrcTransfer(NULL,NULL,eventlist,bb,net_paths[src][dest]); tcpSnk = new TcpSinkTransfer(); } */ //if (connection==1) //tcpSrc->set_app_limit(9000); tcpSrc->setName ("mtcp_" + ntoa (src) + "_" + ntoa (inter) + "_" + ntoa (dest) + "(" + ntoa (connection) + ")"); logfile.writeName (*tcpSrc); tcpSnk->setName ("mtcp_sink_" + ntoa (src) + "_" + ntoa (inter) + "_" + ntoa (dest) + "(" + ntoa (connection) + ")"); logfile.writeName (*tcpSnk); tcpRtxScanner.registerTcp (*tcpSrc); /*int found; do { found = 0; //if (net_paths[src][dest]->size()==K*K/4 && it_sub <= K/2) //choice = rand()%(K/2); //else choice = rand()%net_paths[src][dest]->size(); for (unsigned int cnt = 0;cnt<subflows_chosen.size();cnt++){ if (subflows_chosen.at(cnt)==choice){ found = 1; break; } } }while(found); // */ int choice = 0; #ifdef FAT_TREE choice = rand () % net_paths[src][dest]->size (); #endif #ifdef OV_FAT_TREE choice = rand () % net_paths[src][dest]->size (); #endif #ifdef MH_FAT_TREE if (use_all) { choice = inter; } else { choice = rand () % net_paths[src][dest]->size (); } #endif #ifdef VL2 choice = rand () % net_paths[src][dest]->size (); #endif #ifdef STAR choice = 0; #endif #ifdef BCUBE //choice = inter; int min = -1, max = -1, minDist = 1000, maxDist = 0; if (subflow_count == 1) { //find shortest and longest path for (int dd = 0; dd < net_paths[src][dest]->size (); dd++) { if (net_paths[src][dest]->at (dd)->size () < minDist) { minDist = net_paths[src][dest]->at (dd)->size (); min = dd; } if (net_paths[src][dest]->at (dd)->size () > maxDist) { maxDist = net_paths[src][dest]->at (dd)->size (); max = dd; } } choice = min; } else { choice = rand () % net_paths[src][dest]->size (); } #endif //cout << "Choice "<<choice<<" out of "<<net_paths[src][dest]->size(); subflows_chosen.push_back (choice); /*if (net_paths[src][dest]->size()==K*K/4 && it_sub<=K/2){ int choice2 = rand()%(K/2); */ if (choice >= net_paths[src][dest]->size ()) { printf ("Weird path choice %d out of %u\n", choice, net_paths[src][dest]->size ()); exit (1); } #if PRINT_PATHS paths << "Route from " << ntoa (src) << " to " << ntoa (dest) << " (" << choice << ") -> "; print_path (paths, net_paths[src][dest]->at (choice)); #endif routeout = new route_t (*(net_paths[src][dest]->at (choice))); routeout->push_back (tcpSnk); routein = new route_t (); routein->push_back (tcpSrc); extrastarttime = 50 * drand (); //join multipath connection mtcp->addSubflow (tcpSrc); if (inter == 0) { mtcp->setName ("multipath" + ntoa (src) + "_" + ntoa (dest) + "(" + ntoa (connection) + ")"); logfile.writeName (*mtcp); } tcpSrc->connect (*routeout, *routein, *tcpSnk, timeFromMs (extrastarttime)); #ifdef PACKET_SCATTER tcpSrc->set_paths (net_paths[src][dest]); cout << "Using PACKET SCATTER!!!!" << endl << end; #endif if (ff && !inter) { ff->add_flow (src, dest, tcpSrc); } sinkLogger.monitorSink (tcpSnk); } } } } } //ShortFlows* sf = new ShortFlows(2560, eventlist, net_paths,conns,lg, &tcpRtxScanner); cout << "Mean number of subflows " << ntoa ((double) tot_subs / cnt_con) << endl; // Record the setup int pktsize = TcpPacket::DEFAULTDATASIZE; logfile.write ("# pktsize=" + ntoa (pktsize) + " bytes"); logfile.write ("# subflows=" + ntoa (subflow_count)); logfile.write ("# hostnicrate = " + ntoa (HOST_NIC) + " pkt/sec"); logfile.write ("# corelinkrate = " + ntoa (HOST_NIC * CORE_TO_HOST) + " pkt/sec"); //logfile.write("# buffer = " + ntoa((double) (queues_na_ni[0][1]->_maxsize) / ((double) pktsize)) + " pkt"); double rtt = timeAsSec (timeFromUs (RTT)); logfile.write ("# rtt =" + ntoa (rtt)); // GO! double last = 0.0; while (eventlist.doNextEvent ()) { if (timeAsMs(eventlist.now())>last+10.0) { cout << (last = timeAsMs(eventlist.now())) << endl; for (vector<MultipathTcpSrc*>::iterator iA = mptcpVector.begin(); iA!=mptcpVector.end(); iA++) { cout << (*iA)->compute_total_bytes()*0.001*0.001 <<" "; } cout << endl; } } }