1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
|
# ----------------------- Test XCP Performance ------------------------------#
#
# Author: Dina Katabi, dina@ai.mit.edu
# Last Update : 7/16/2002
#
#-------------------------------------------------------------------------------#
#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- Utility Functions -*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-#
#--------- Creating the TOPOLOGY --------------------#
# n0
# : \ Bottleneck
# : R0-----------------------R1
# /
# ni
#
Agent/TCP set minrto_ 1
proc set-red-params { qsize } {
Queue/RED set thresh_ [expr 0.6 * $qsize]
Queue/RED set maxthresh_ [expr 0.8 * $qsize]
Queue/RED set q_weight_ 0.001
Queue/RED set linterm_ 10
Queue/RED set bytes_ false ;
Queue/RED set queue_in_bytes_ false ;
Agent/TCP set old_ecn_ true
Queue/RED set setbit_ true
}
proc create-topology2 { BW delay qtype qsize numSideLinks deltaDelay } {
global ns
#Set the queue size to the pipe's size assuming the packet size is 1000 KByte
if { $qsize == 0 } { set qsize [expr round([expr ($BW / 8) * 2 * $delay])] }
set i 0
while { $i < 2 } {
global R$i
set R$i [$ns node]
incr i
}
$ns duplex-link $R0 $R1 [set BW]Mb [set delay]ms $qtype
$ns queue-limit $R0 $R1 $qsize
$ns queue-limit $R1 $R0 $qsize
# Give a global handle to the Bottleneck Queue to allow
# setting the RED paramters
global Bottleneck rBottleneck
set Bottleneck [[$ns link $R0 $R1] queue]
set rBottleneck [[$ns link $R1 $R0] queue]
global l rl
set l [$ns link $R0 $R1]
set rl [$ns link $R1 $R0]
global all_links
set all_links "$l $rl "
# The side links have the same BW as the Bottleneck
set i 0
while { $i < $numSideLinks } {
global n$i q$i rq$i l$i rl$i
set n$i [$ns node]
$ns duplex-link [set n$i] $R0 [set BW]Mb [expr $delay + $i * $deltaDelay]ms $qtype
$ns queue-limit [set n$i] $R0 $qsize
$ns queue-limit $R0 [set n$i] $qsize
set q$i [[$ns link [set n$i] $R0] queue]
set rq$i [[$ns link $R0 [set n$i]] queue]
set l$i [$ns link [set n$i] $R0]
set rl$i [$ns link $R0 [set n$i]]
set all_links "$all_links [set l$i] [set rl$i] "
incr i
}
}
#------- Sender Class :
# This is essentially an ftp sender
Class GeneralSender -superclass Agent
# otherparams are "startTime TCPclass .."
GeneralSender instproc init { id node rcvrTCP otherparams } {
global ns
$self next
$self instvar tcp_ id_ ftp_ node_ tcp_rcvr_ tcp_type_
set id_ $id
set node_ $node
if { [llength $otherparams] > 1 } {
set TCP [lindex $otherparams 1]
} else {
set TCP "TCP/Reno"
}
set tcp_type_ $TCP
set tcp_ [new Agent/$TCP]
$tcp_ set packetSize_ 1000
$tcp_ set class_ $id
set ftp_ [new Source/FTP]
$ftp_ set agent_ $tcp_
$ns attach-agent $node $tcp_
$ns connect $tcp_ $rcvrTCP
set tcp_rcvr_ $rcvrTCP
set startTime [lindex $otherparams 0]
$ns at $startTime "$ftp_ start"
puts "initialized Sender $id_ at $startTime"
}
GeneralSender instproc trace-xcp parameters {
$self instvar tcp_ id_ tcpTrace_
global ftracetcp$id_
set ftracetcp$id_ [open xcp$id_.tr w]
set tcpTrace_ [set ftracetcp$id_]
$tcp_ attach-trace [set ftracetcp$id_]
if { -1 < [lsearch $parameters cwnd] } { $tcp_ tracevar cwnd_ }
if { -1 < [lsearch $parameters seqno] } { $tcp_ tracevar t_seqno_ }
}
#--- Command line arguments
proc set-cmd-line-args { list_args } {
global argv
set i 0
foreach a $list_args {
global $a
set $a [lindex $argv $i]
puts "$a = [set $a]"
incr i
}
}
#-------------- Plotting functions -----------#
# plot a xcp traced var
proc plot-xcp { TraceName nXCPs PlotTime what } {
if {[string compare $what "cwnd_"] == 0} {
exec rm -f xgraph_cwnd.tcp
set f [open xgraph_cwnd.tcp w]
set a cwnd
} else {
exec rm -f xgraph_seqno.tcp
set f [open xgraph_seqno.tcp w]
set a seqno
}
puts $f "TitleText: $TraceName"
puts $f "Device: Postscript"
foreach i $nXCPs {
#the TCP traces are flushed when the sources are stopped
exec rm -f temp.tcp
exec touch temp.tcp
global ftracetcp$i
if [info exists ftracetcp$i] { flush [set ftracetcp$i] }
set packetsize [expr 100 * ($i +10)]
set result [exec awk -v PlotTime=$PlotTime -v what=$what -v s=$packetsize {
{
if (( $6 == what ) && ($1 > PlotTime)) {
tmp=$7*s
print $1, tmp >> "temp.tcp";
}
}
} xcp$i.tr]
puts "$i : $result"
puts $f \"$what$i
exec cat temp.tcp >@ $f
puts $f "\n"
flush $f
}
close $f
exec xgraph -nl -m -x time -y $what xgraph_$a.tcp &
return
}
# Takes as input the the label on the Y axis, the time it starts plotting, and the trace file tcl var
proc plot-red-queue { TraceName PlotTime traceFile } {
exec rm -f xgraph.red_queue
exec rm -f temp.q temp.a temp.p temp.avg_enqueued temp.avg_dequeued temp.x temp.y
exec touch temp.q temp.a temp.p temp.avg_enqueued temp.avg_dequeued temp.x temp.y
exec awk -v PT=$PlotTime {
{
if (($1 == "q" && NF>2) && ($2 > PT)) {
print $2, $3 >> "temp.q"
}
else if (($1 == "a" && NF>2) && ($2 > PT)){
print $2, $3 >> "temp.a"
}
else if (($1 == "p" && NF>2) && ($2 > PT)){
print $2, $3 >> "temp.p"
}
}
} $traceFile
set ff [open xgraph.red_queue w]
puts $ff "TitleText: $TraceName"
puts $ff "Device: Postscript \n"
puts $ff \"queue
exec cat temp.q >@ $ff
puts $ff \n\"ave_queue
exec cat temp.a >@ $ff
puts $ff \n\"prob_drop
exec cat temp.p >@ $ff
close $ff
exec xgraph -P -x time -y queue xgraph.red_queue &
}
proc plot-red {varname filename PlotTime} {
exec rm -f temp.$filename
exec touch temp.$filename
set result [exec awk -v PlotTime=$PlotTime -v what=$varname -v file=temp.$filename {
{
if (( $1 == what ) && ($2 > PlotTime)) {
print $2, $3 >> file ;
}
}
} ft_red_Bottleneck.tr]
exec xgraph -P -x time -y $filename temp.$filename
}
#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- Initializing Simulator -*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-#
# BW is in Mbs and delay is in ms
#set-cmd-line-args "seed qType BW nXCPs delay "
set seed 472904
set qType XCP
set BW 20; # in Mb/s
set nXCPs 3; # Number of flows
set delay 10; # in ms
set ns [new Simulator]
$ns use-scheduler Heap
set rtg [new RNG]
$rtg seed $seed
set f_all [open out.tr w]
$ns trace-all $f_all
set qSize [expr round([expr ($BW / 8.0) * 4 * $delay * 1.0])];#set buffer to the pipe size
set tracedXCPs "0 1 2"
set SimStopTime 30
set PlotTime 0
#---------- Create the simulation --------------------#
# Create topology
create-topology2 $BW $delay $qType $qSize $nXCPs 0.0
foreach link $all_links {
set queue [$link queue]
switch $qType {
"XCP" {
$queue set-link-capacity [[$link set link_] set bandwidth_];
}
"DropTail/XCP" {
$queue set-link-capacity-Kbytes [expr [[$link set link_] set bandwidth_] / 8000];
}
default {
puts "Incorrect qType $qType"
exit 0
}
}
}
# Create sources:
set i 0
while { $i < $nXCPs } {
set StartTime [expr [$rtg integer 1000] * 0.001 * (0.01 * $delay) + $i * 6.0]
set rcvr_XCP [new Agent/TCPSink/XCPSink]
$ns attach-agent $R1 $rcvr_XCP
set src$i [new GeneralSender $i [set n$i] $rcvr_XCP "$StartTime TCP/Reno/XCP"]
[[set src$i] set tcp_] set packetSize_ [expr 100 * ($i +10)]
[[set src$i] set tcp_] set window_ [expr $qSize * 10]
incr i
}
#---------- Trace --------------------#
# Trace sources
foreach i $tracedXCPs {
[set src$i] trace-xcp "cwnd seqno"
}
# Trace Queues
foreach queue_name "Bottleneck rBottleneck" {
set queue [set "$queue_name"]
switch $qType {
"XCP" {
global "ft_red_$queue_name"
set "ft_red_$queue_name" [open ft_red_[set queue_name].tr w]
set xcpq $queue ;#[$queue set vq_(0)]
$xcpq attach [set ft_red_$queue_name]
}
"DropTail/XCP" {}
}
}
#---------------- Run the simulation ------------------------#
proc flush-files {} {
set files "f_all ft_red_Bottleneck ft_red_rBottleneck"
global tracedXCPs
foreach file $files {
global $file
if {[info exists $file]} {
flush [set $file]
close [set $file]
}
}
foreach i $tracedXCPs {
global src$i
set file [set src$i tcpTrace_]
if {[info exists $file]} {
flush [set $file]
close [set $file]
}
}
}
proc finish {} {
global ns
if {[info exists f]} {
$ns flush-trace
close $f
}
$ns halt
}
$ns at $SimStopTime "finish"
$ns run
flush-files
#------------ Post Processing ---------------#
set PostProcess 1
if { $PostProcess } {
#--- Traced TCPs
set TraceName "Flows --$qType-QS$qSize"
plot-xcp $TraceName $tracedXCPs 0.0 "cwnd_"
# plot-xcp $TraceName $tracedXCPs 0.0 "t_seqno_"
# plot-red-queue $TraceName $PlotTime ft_red_Bottleneck.tr
plot-red "u" util 0.0
}
|