def verify_bandwidth(net): print "Verifying bandwidth..." # Start iperf server. server = net.getNodeByName('h%d' % (args.n-1)) print "Starting iperf server..." cmd = "iperf -s -w 16m" print cmd s = server.popen(cmd) # Start the iperf client on h1. Ensure that you create a long lived TCP flow. client = net.getNodeByName('h0') print "Starting iperf client..." cmd = "iperf -c %s -t %d" % (server.IP(), LONG_TIME_SECONDS) print cmd c = client.popen(cmd) # Get measurements. I only measure one flow because the hosts are created identically. iface = 's0-eth%d' % args.n rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES+CALIBRATION_SKIP) rates = rates[CALIBRATION_SKIP:] med = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) fraction = med / args.bw_net cprint ("Verify bandwidth median: %.3f max: %.3f stdev: %.3f frac: %.3f" % (med, ru_max, ru_stdev, fraction), 'blue') sys.stdout.flush() # Shut down iperf processes os.system('killall -9 iperf') return (fraction >= TARGET_UTIL_FRACTION)
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 nflows = args.nflows * (args.n - 1) min_q, max_q = 1, int(bdp) # Set a higher speed on the bottleneck link in the beginning so # flows quickly connect set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() print 'Connections %d/%d succeeded\r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 # Set the speed back to the bottleneck link speed. set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 while reference_rate <= args.bw_net * START_BW_FRACTION: rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES + CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint( "Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() while abs(min_q - max_q) >= 2: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() set_q(iface, mid) rates = get_rates(iface) print "measured rates: %s" % rates rate_avg = avg(rates) rate_median = median(rates) if (ok(rate_median / args.bw_net)): max_q = mid else: min_q = mid monitor.terminate() print "*** Minq for target: %d" % max_q return max_q
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 nflows = args.nflows * (args.n - 1) min_q, max_q = 1, int(bdp) # Set a higher speed on the bottleneck link in the beginning so # flows quickly connect set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() print 'Connections %d/%d succeeded\r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 # TODO: Set the speed back to the bottleneck link speed. set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 while reference_rate <= args.bw_net * START_BW_FRACTION: rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES+CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint ("Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() while abs(min_q - max_q) >= 2: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() # TODO: Binary search over queue sizes. # (1) Check if a queue size of "mid" achieves required utilization # based on the median value of the measured rate samples. # (2) Change values of max_q and min_q accordingly # to continue with the binary search # You may use the helper functions set_q(), # get_rates(), avg(), median() and ok() # Note: this do_sweep function does a bunch of setup, so do # not recursively call do_sweep to do binary search. monitor.terminate() print "*** Minq for target: %d" % max_q return max_q
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" # bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 nflows = args.nflows * (args.n - 1) min_q, max_q = 12000, int(bdp) # Set a higher speed set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() # "输出 \r 能够起到刷新效果..." print 'Connections %d/%d \r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() if args.red: # set_q_red() # inital with red cmd = ("tc qdisc del dev %s parent 5:1 " % (iface)) dprint(cmd) os.system(cmd) cmd = ("tc qdisc add dev %s parent 5:1 " "handle 10: red limit %d avpkt %d" % (iface, max_q, AVPKT)) dprint(cmd) os.system(cmd) else: set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 # 测试带宽, 或是模拟 if not args.simu_rate: while reference_rate <= args.bw_net * START_BW_FRACTION: # 获取带宽大小 rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES + CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint( "Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() else: reference_rate = 61.536 cprint( "模拟速率, 跳过之前的速率检测 Reference rate median: %.3f" % (reference_rate), 'yellow') # 增加 qlen > 12000 的判断条件, 避免设置过低 limit 对 red 也不起左右 while abs(min_q - max_q) >= 2000 and min_q >= 12000 and max_q >= 12000: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() ######################### Begin: delete code # TODO: Check if a queue size of # "mid" is valid. You may use the helper functions set_q(), # get_rates(), avg(), median() and ok() current_rate = -1 if args.red: set_q_red(iface, mid) else: set_q(iface, mid) rates = get_rates(iface) current_rate = median(rates) fraction = current_rate / reference_rate print " Utilisation %s [%s]" % (format_fraction(fraction), format_floats(rates)) if ok(fraction): max_q = mid else: #min_q = mid + 1 min_q = mid + 1000 print "debug: incr min_q from %d to %d" % (mid, min_q) ######################## End: delete code ############################## monitor.terminate() print "*** Minq for target: %d" % max_q return max_q
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 nflows = args.nflows * (args.n - 1) min_q, max_q = 1, int(bdp) # Set a higher speed on the bottleneck link in the beginning so # flows quickly connect set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() print 'Connections %d/%d succeeded\r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 # Set the speed back to the bottleneck link speed. set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 while reference_rate <= args.bw_net * START_BW_FRACTION: rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES+CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint ("Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() while abs(min_q - max_q) >= 2: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() set_q(iface, mid) rates = get_rates(iface) print "measured rates: %s" % rates rate_avg = avg(rates) rate_median = median(rates) if (ok(rate_median/args.bw_net)): max_q = mid else: min_q = mid monitor.terminate() print "*** Minq for target: %d" % max_q return max_q
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 nflows = args.nflows * (NUM_HOSTS - 1) min_q, max_q = 1, int(bdp) # Set a higher speed set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() print 'Connections %d/%d \r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 while reference_rate <= args.bw_net * START_BW_FRACTION: rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES + CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint( "Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() while abs(min_q - max_q) >= 2: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() # TODO: Binary search over queue sizes # (1) Check if a queue size of "mid" achieves required utilization # based on the median value of the measured rate samples. # (2) Change values of max_q and min_q accordingly # to continue with the binary search # You may use the helper functions set_q(), # get_rates(), avg(), median() and ok() monitor.terminate() print "*** Minq for target: %d" % max_q return max_q
def do_sweep(iface): """Sweep queue length until we hit target utilization. We assume a monotonic relationship and use a binary search to find a value that yields the desired result""" bdp = args.bw_net * 2 * args.delay * 1000.0 / 8.0 / 1500.0 nflows = args.nflows * (args.n - 1) min_q, max_q = 1, int(bdp) # Set a higher speed set_speed(iface, "2Gbit") succeeded = 0 wait_time = 300 while wait_time > 0 and succeeded != nflows: wait_time -= 1 succeeded = count_connections() print 'Connections %d/%d \r' % (succeeded, nflows), sys.stdout.flush() sleep(1) monitor = Process(target=monitor_qlen, args=(iface, 0.01, '%s/qlen_%s.txt' % (args.dir, iface))) monitor.start() if succeeded != nflows: print 'Giving up' return -1 set_speed(iface, "%.2fMbit" % args.bw_net) print "\nSetting q=%d " % max_q, sys.stdout.flush() set_q(iface, max_q) # Wait till link is 100% utilised and train reference_rate = 0.0 while reference_rate <= args.bw_net * START_BW_FRACTION: rates = get_rates(iface, nsamples=CALIBRATION_SAMPLES+CALIBRATION_SKIP) print "measured calibration rates: %s" % rates # Ignore first N; need to ramp up to full speed. rates = rates[CALIBRATION_SKIP:] reference_rate = median(rates) ru_max = max(rates) ru_stdev = stdev(rates) cprint ("Reference rate median: %.3f max: %.3f stdev: %.3f" % (reference_rate, ru_max, ru_stdev), 'blue') sys.stdout.flush() while abs(min_q - max_q) >= 2: mid = (min_q + max_q) / 2 print "Trying q=%d [%d,%d] " % (mid, min_q, max_q), sys.stdout.flush() ######################### Begin: delete code # TODO: Check if a queue size of # "mid" is valid. You may use the helper functions set_q(), # get_rates(), avg(), median() and ok() current_rate = -1 set_q(iface, mid) rates = get_rates(iface) current_rate = median(rates) fraction = current_rate / reference_rate print " Utilisation %s [%s]" % ( format_fraction(fraction), format_floats(rates)) if ok(fraction): max_q = mid else: min_q = mid + 1 ######################## End: delete code ############################## monitor.terminate() print "*** Minq for target: %d" % max_q return max_q