ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΕΙΡΑΙΩΣ ΤΜΗΜΑ ΨΗΦΙΑΚΩΝ ΣΥΣΤΗΜΑΤΩΝ 2 η Άσκηση για το μάθημα: Συστήματα Ουρών Αναμονής «Μελέτη συστήματος αναμονής M/M/1 με χρήση του Network Simulator-2» Υπεύθυνοι Καθηγ. Π. Δεμέστιχας Δρ. Κ. Τσαγκάρης Δρ. Μ. Λογοθέτης
1. ΤΥΧΑΙΕΣ ΜΕΤΑΒΛΗΤΕΣ ΚΑΙ NS-2 Στον ns μπορούν να δημιουργηθούν τυχαίες μεταβλητές (Random Variables-RVs) με διάφορες κατανομές. 1.1. Σπορές (seeds) και γεννήτριες (generators) Εκτός από την κατανομή της, υπάρχουν και κάποιες άλλες πτυχές που πρέπει να ληφθούν υπόψη όταν προσομοιώνουμε μια τυχαία μεταβλητή: Θέλουμε να λαμβάνουμε την ίδια τιμή της τυχαίας μεταβλητής όταν εκτελούμε και πάλι την προσομοίωση (πιθανόν μεταβάλλοντας κάποιες άλλες παραμέτρους των προσομοιώσεων); Κάτι τέτοιο θα μας επέτρεπε να συγκρίνουμε απευθείας, για ένα μεμονωμένο τυχαίο σύνολο γεγονότων, πώς τα αποτελέσματα προσομοίωσης εξαρτώνται από κάποιες φυσικές παραμέτρους (όπως καθυστερήσεις γραμμών ή μήκος ουράς). Συχνά θέλουμε τυχαίες μεταβλητές που να είναι ανεξάρτητες μεταξύ τους Η παραγωγή τυχαίων μεταβλητών χρησιμοποιεί μία σπορά ή σπόρο (seed). Σε ένα tcl script ο σπόρος δηλώνεται από έναν αριθμό. Η τιμή 0 για τον σπόρο οδηγεί στην παραγωγή μιας νέας τυχαίας μεταβλητής κάθε φορά που τρέχουμε την προσομοίωση. Επομένως, αν θέλουμε να έχουμε τις ίδιες τυχαίες μεταβλητές για διαφορετικές προσομοιώσεις, θα πρέπει να αποθηκεύσουμε τις παραπάνω παραχθείσες τιμές των τυχαίων μεταβλητών. Αντιθέτως, αν χρησιμοποιούμε άλλους σπόρους τότε κάθε φορά που τρέχουμε την προσομοίωση, η ίδια ακολουθία τιμών τυχαίων μεταβλητών που παράγονται σε μία προσομοίωση θα επαναλαμβάνεται. Στον ns, αν χρησιμοποιούμε διαφορετικές γεννήτριες με τον ίδιο σπόρο και την ίδια κατανομή, θα παίρνουμε τις ίδιες τιμές για τις τυχαίες μεταβλητές (εκτός αν ο σπόρος τίθεται 0 ). Αυτό θα το δούμε και σε ένα παράδειγμα αργότερα. 1.2. Δημιουργία Τυχαίων Μεταβλητών Αρχικά δημιουργούμε μια νέα γεννήτρια και της αναθέτουμε ένα σπόρο, π.χ. 2, με την εντολή set MyRng1 [new RNG] $MyRng1 seed 2 Στη συνέχεια και εφόσον δημιουργήσαμε μια τυχαία μεταβλητή, πρέπει να δηλώσουμε τον τύπο της κατανομής της και τις παραμέτρους τους. Για το σκοπό αυτό παρατίθενται κάποια παραδείγματα στα οποία δημιουργούμε τυχαίες μεταβλητές με κατανομές Pareto, Σταθερή (Constant), Ομοιόμορφη (Uniform), Εκθετική (Exponential) και Υπερ-εκθετική (Hyper- Exponential), αντίστοιχα: 1. Pareto. Μια τυχαία μεταβλητή r 1 κατανεμημένη κατά Pareto δημιουργείται καθορίζοντας την προσδοκητή τιμή της και την παράμετρο (shape parameter), με προεπιλεγμένες τιμές 1.0 και 1.5, αντίστοιχα. set r1 [new RandomVariable/Pareto] $r1 use-rng $MyRng $r1 set avg_ 10.0-2-
$r1 set shape_ 1.2 2. Σταθερή. Μια εκφυλισμένη τυχαία μεταβλητή θεωρείται η σταθερή που ισούται με την τιμή της set r2 [new RandomVariable/Constant] $r1 use-rng $MyRng $r1 set val_ 5.0 3. Ομοιόμορφη (Uniform). Ορίζεται από ένα μέγιστο και ένα ελάχιστο σημείο που διαμορφώνουν την ομοιόμορφη κατανομή. set r3 [new RandomVariable/Uniform] $r3 use-rng $MyRng $r3 set min_ 0.0 $r3 set max_ 10.0 4. Εκθετική (Exponential). Ορίζεται από τη μέση τιμής της. set r4 [new RandomVariable/Exponential] $r4 use-rng $MyRng $r4 set avg_ 5 5. Υπερ-Εκθετική (Hyper-Exponential). Ορίζεται ως ακολούθως: set r5 [new RandomVariable/HyperExponential] $r5 use-rng $MyRng $r5 set avg_ 1.0 $r5 set cov_ 4.0 Στη συνέχεια παρατίθεται ένα μικρό tcl script (rv1.tcl) που εξετάζει τυχαίες μεταβλητές κατανεμημένες κατά Pareto, με διαφορετικούς σπόρους και γεννήτριες μα με την ίδια κατανομή, (όπως είπαμε Pareto). -3-
####################### ### Rv1.tcl ### ####################### set count 3 for {set i 0 {$i<3 {incr i { puts "===== i = $i " set MyRng1 [new RNG] $MyRng1 seed $i set MyRng2 [new RNG] $MyRng2 seed $i set r1 [new RandomVariable/Pareto] $r1 use-rng $MyRng1 $r1 set avg_ 10.0 $r1 set shape_ 1.2 puts stdout "Testing Pareto Distribution, avg = [$r1 set avg_] shape = [$r1 set shape_]" $r1 test $count set r2 [new RandomVariable/Pareto] $r2 use-rng $MyRng2 $r2 set avg_ 10.0 $r2 set shape_ 1.2 puts stdout "Testing Pareto Distribution, avg = [$r2 set avg_] shape = [$r2 set shape_]" $r2 test $count ############################################## -4-
Για κάθε σπόρο (seed με τιμές 0, 1 και 2) και γεννήτρια, δημιουργούμε μια ακολουθία 3 τυχαίων μεταβλητών. Η μεταβλητή count παίρνει τον αριθμό των τυχαίων μεταβλητών που δημιουργούμε με χρήση της test για κάθε σπόρο και γεννήτρια. Εκτελώντας το παράδειγμα (ns rv1.tcl), μπορούμε να παρατηρήσουμε ότι για σπόρο 0, οι δύο γεννήτριες δίνουν διαφορετικές τιμές μεταβλητών. Επομένως, λαμβάνουμε συνολικά 6 διαφορετικές τιμές (3 για κάθε γεννήτρια). Για άλλους σπόρους, μια γεννήτρια δημιουργεί 3 διαφορετικές τιμές, αλλά αυτές οι τιμές δεν εξαρτώνται από τη γεννήτρια: Η ν-οστή τιμή που δημιουργείται από τη γεννήτρια 1 είναι η ίδια με τη ν-οστή τιμή που δημιουργείται από τη γεννήτρια 2. 2. ΕΠΕΞΕΡΓΑΣΙΑ ΑΡΧΕΙΩΝ ΜΕ ΧΡΗΣΗ PERL Η γλώσσα PERL (Practical Extraction and Report Language) επιτρέπει το φιλτράρισμα και την επεξεργασία ASCII αρχείων πληροφορίας. Η γλώσσα αυτή δημιουργήθηκε από τον Larry Wall με μοναδικό στόχο την απλοποίηση την διαχείρισης συστημάτων. Η Perl εξελίχθηκε πολύ και σήμερα είναι μια γλώσσα γενικού σκοπού και αποτελεί ένα από τα πλέον χρήσιμα εργαλεία για τη διαχείριση πληροφορίας Web και Internet. Η Perl έχει πολλές χρήσεις, αλλά κυρίως επικεντρώνεται στην αναζήτηση (search), εξαγωγή (extraction) και αναφορά (report). Βασικά πλεονεκτήματα από τη χρήση Perl είναι: Η εύκολη υλοποίηση μικρών προγραμμάτων που θα χρησιμοποιηθούν ως φίλτρα για την εξαγωγή πληροφορίας από μεγάλα text αρχεία Η Perl «παίζει» σε όλα σχεδόν τα λειτουργικά συστήματα χωρίς αλλαγή του κώδικα (μεταφερσιμότητα) Η συντήρηση και απασφαλμάτωση των Perl scripts είναι γενικά εύκολες διαδικασίες. Η Perl είναι τόσο δημοφιλής, ώστε να μπορεί κανείς να βρει μεγάλο αριθμό έτοιμων προγραμμάτων στο διαδίκτυο. Στην παρούσα εργασία θα χρησιμοποιήσετε το κάτωθι Perl script column.pl #!/usr/bin/perl # Mark Claypool # Last significantly modified: December, 2001 # This program prints out fields of an indicated column. # The columns are numbered 0, 1, 2, 3... require 'getopts.pl'; &ParseCommandLine; $line = <STDIN>; while ($line) { $line =~ s/^\s+//; # remove initial white-space $line =~ s/\s+/ /g; # turn double-space into single space @word = split($split,$line); # columns will then be $1, $2, $3... $i =0; while ($i <= $#col) { print "@word[@col[$i]]\t"; $i += 1; -5-
print "\n"; $line = <STDIN>; exit; ####################################################################### # ParseCommandLine # check for the right number of command line arguments # print usage message and quit if there is an error # global variables are @col sub ParseCommandLine { # get token to split on &Getopts('t:'); if ($opt_t) { $split = $opt_t; else { $split = '\s+'; # get columns while ($#ARGV >= 0) { $arg = shift(@argv); if ($arg =~ /^(\d+)/) { push(@col, $1); else { &usage; if ($#col < 0) { &usage; ########################################################################## # usage # print a usage message and quit sub usage { print STDERR "column: print fields from an indicated column\n"; print STDERR "Usage: column <flags>, where flags are:\n"; print STDERR " [-t str]\ttoken to use as a separator (default is white space)\n"; print STDERR " 0,1,2...\n"; exit; {# [#...]\tcolumn(s) to print, numbered -6-
To script column.pl χρησιμοποιείται ως εξής: perl column.pl 0 1 < qm.out όπου οι αριθμοί 0, 1 δηλώνουν ότι θέλουμε να τυπωθούν η πρώτη και η δεύτερη κ.ο.κ στήλη του αρχείου qm.out, το οποίο είναι και το προς επεξεργασία αρχείο. Με την παραπάνω εντολή τα αποτελέσματα θα αποτυπωθούν στην οθόνη. Αν θέλουμε να τα έχουμε στη διάθεσή μας για περαιτέρω επεξεργασία (κάτι που είναι και το πιο σύνηθες), θα πρέπει να τα ανακατευθύνουμε σε αρχείο της επιλογής μας. Δηλαδή: perl column.pl 0 1 < qm.out > MyOutFile 3. ΜΟΝΤΕΛΑ ΑΝΑΜΟΝΗΣ ΚΑΙ NS-2 Ο προσομοιωτής ns-2 μπορεί να χρησιμοποιηθεί για την προσομοίωση των κλασικών μοντέλων αναμονής. Στα απλούστερα μοντέλα αναμονής, ο χρόνος μεταξύ διαδοχικών αφίξεων πακέτων είναι τυχαίος και γενικά υπακούει σε κάποια γενική κατανομή πιθανότητας. Ομοίως, ο χρόνος που χρειάζεται για την μετάδοση ενός πακέτου είναι επίσης τυχαίος και επίσης κατανεμημένος σύμφωνα με κάποια άλλη κατανομή. Το γεγονός ότι ο χρόνος μετάδοσης ποικίλει μπορεί να αντικατοπτρίζει μια κατάσταση κατά την οποία ο ρυθμός μετάδοσης παραμένει σταθερός αλλά μεταβάλλεται το μέγεθος του πακέτου. 3.1. Προσομοίωση ουράς M/M/1 Το απλούστερο παράδειγμα ουράς για μαθηματική ανάλυση είναι η ουρά M/M/1. Υπενθυμίζεται ότι σε μια ουρά M/M/1 οι χρόνοι μεταξύ διαδοχικών αφίξεων (interarrival times) είναι εκθετικά κατανεμημένοι με κάποια παράμετρο, έστω, και ο χρόνος εξυπηρέτησης πακέτου (που δεν είναι τίποτε άλλα παρά ο χρόνος μετάδοσης του πακέτου) υπακούει επίσης σε μια εκθετική κατανομή, έστω με παράμετρο. Ένα πακέτο μεταδίδεται κάθε φορά και το μέγεθος του καταχωρητή (buffer) θεωρείται άπειρο. Ορίζοντας, το μέσο πλήθος πακέτων στο σύστημα (ουρά και εξυπηρέτηση) θα δίνεται από τη σχέση: n 1 Ακολουθεί το αρχείο προσομοίωσης μιας τέτοιας ουράς, mm1.tcl. set ns [new Simulator] set tf [open out.tr w] $ns trace-all $tf set lambda 30.0 set mu 33.0 set n1 [$ns node] set n2 [$ns node] -7-
# Εφόσον τα μεγέθη πακέτων στρογγυλοποιούνται σε κάποιο ακέραιο αριθμό #bytes, θα πρέπει να έχουμε μεγάλα πακέτα και μικρά σφάλματα #στρογγυλοποίησης, επομένως θεωρούμε μεγάλο bandwidth set link [$ns simplex-link $n1 $n2 100kb 0ms DropTail] $ns queue-limit $n1 $n2 100000 set rng1 [new RNG] $rng1 seed 0 set rng2 [new RNG] $rng2 seed 0 # παραγωγή τυχαίων χρόνων μεταξύ διαδοχικών αφίξεων και μεγεθών πακέτων set InterArrivalTime [new RandomVariable/Exponential] $InterArrivalTime use-rng $rng1 $InterArrivalTime set avg_ [expr 1/$lambda] set pktsize [new RandomVariable/Exponential] $pktsize use-rng $rng2 $pktsize set avg_ [expr 100000.0/(8*$mu)] set src [new Agent/UDP] $ns attach-agent $n1 $src # παρακολούθηση ουράς set qmon [$ns monitor-queue $n1 $n2 [open qm1.out w] 0.1] $link queue-sample-timeout proc finish { { global ns tf $ns flush-trace close $tf exit 0-8-
# Με τη διαδικασία sendpacket προγραμματίζονται οι αφίξεις των νέων #πακέτων και τίθενται τα μεγέθη αυτών, χρησιμοποιώντας τις τυχαίες #μεταβλητές (εκθετικές) που έχουμε ορίσει παραπάνω. proc sendpacket { { global ns src InterArrivalTime pktsize set time [$ns now] $ns at [expr $time + [$InterArrivalTime value]] "sendpacket" set bytes [expr round ([$pktsize value])] $src send $bytes set sink [new Agent/Null] $ns attach-agent $n2 $sink $ns connect $src $sink $ns at 0.0001 "sendpacket" $ns at 2000.0 "finish" $ns run Η προσομοίωση παράγει ένα αρχείο ίχνους (trace file) out.tr με όλα τα γεγονότα, και επίσης ένα αρχείο ίχνους που προκύπτει από παρακολούθηση της ουράς και το οποίο ονομάζεται qm.out. Επικεντρώνουμε στο αρχείο παρακολούθησης της ουράς, qm.out και βλέπουμε ένα δείγμα από τη μορφή του. 1.4000000000000001 0 1 876.50857851999626 2.2510863799999892 31 30 0 11444 11021 0 1.5000000000000002 0 1 28.405070159998289 0.24809395999999739 34 34 0 11772 11772 0 1.6000000000000003 0 1 0.0 0.0 36 36 0 12050 12050 0 1.7000000000000004 0 1 0.0 0.0 37 37 0 12105 12105 0 1.8000000000000005 0 1 0.0 0.0 39 39 0 13142 13142 0 1.9000000000000006 0 1 305.71571978000543 2.300752980000027 46 43 0 14312 13739 0 2.0000000000000004 0 1 266.49097009999207 0.63661733999996173 48 48 0 15626 15626 0 2.1000000000000005 0 1 0.0 0.0 48 48 0 15626 15626 0 2.2000000000000006 0 1 0.0 0.0 48 48 0 15626 15626 0 2.3000000000000007 0 1 41.413800400010913 0.11757092000002956 52 50 0 17508 16763 0 2.4000000000000008 0 1 951.26771259999418 2.3953966599999821 53 52 0 17938 17508 0-9-
Η γενική μορφή ενός αρχείου ίχνους ουράς είναι η παρακάτω: time src dst size(b) size(pkts) parrivals pdepartures pdrops barrivals bdepartures bdrops Όπου, time = χρονική στιγμή παρακολούθησης ουράς. src = κόμβος αποστολέας dst = κόμβος αποδέκτης size(b) = στιγμιαίο μέγεθος ουράς σε bytes. size(pkts) = στιγμιαίο μέγεθος ουράς σε packets. parrivals = τρέχον σύνολο πακέτων που έχουν αφιχθεί μέχρι και τη στιγμή time. pdepartures = τρέχον σύνολο πακέτων που έχουν αναχωρήσει μέχρι τη στιγμή time (προσοχή: όχι απορριφθέντα). pdrops = συνολικός αριθμός απορριφθέντων πακέτων barrivals = τρέχον σύνολο bytes περιεχόμενων στα πακέτα που έχουν αφιχθεί. bdepartures = τρέχον σύνολο bytes περιεχόμενων στα πακέτα που έχουν αναχωρήσει μέχρι τη στιγμή time (προσοχή: όχι απορριφθέντα). bdrops = συνολικός αριθμός απορριφθέντων bytes Μπορούμε να χρησιμοποιήσουμε το Perl script column.pl και να απομονώσουμε συγκεκριμένες στήλες από το παραχθέν αρχείο. Αναπαριστώντας γραφικά τα στοιχεία της στήλης 5 (μέγεθος ουράς σε πακέτα) σε συνάρτηση με το χρόνο (time) λαμβάνουμε την εξέλιξη του μήκους της ουράς. 4. ΕΡΩΤΗΜΑΤΑ Κάνοντας χρήση του tcl αρχείου mm1.tcl. που είδαμε παραπάνω, να γίνει προσομοίωση ουράς Μ/Μ/1 με ρυθμό λ=30 πακέτα/sec και μ=33 πακέτα/sec. Στη συνέχεια, να απαντηθούν τα παρακάτω ερωτήματα: 1. Να γίνει η γραφική παράσταση του πλήθους πακέτων στην ουρά του συστήματος (αρ. πακέτων ανά sec). 2. Να βρεθεί το μέσο πλήθος πακέτων στο σύστημα και να γίνει σύγκριση με το θεωρητικό αναμενόμενο αποτέλεσμα που δίνεται από τον τύπο E n 1 3. Να βρεθεί ο ρυθμός απωλειών στο σύστημα και να συγκριθεί με το θεωρητικό αναμενόμενο αποτέλεσμα. 4. Να βρεθεί ο ρυθμός εξυπηρέτησης (χρησιμοποίηση) του συστήματος και να συγκριθεί με το αναμενόμενο αποτέλεσμα. -10-
5. Να βρεθεί ο μέσος χρόνος αναμονής στην ουρά και να συγκριθεί με τον αντίστοιχο θεωρητικό E W q p n 6. Να βρεθούν οι πιθανότητες, για n 0,1,2,3,4, 5 όπου η δηλώνει την πιθανότητα να έχουμε n πακέτα στο σύστημα και να συγκριθούν με τις θεωρητικά αναμενόμενες τιμές που δίνονται από τον τύπο p n ( 1 ) n 7. Υπάρχει διαφορά ανάμεσα στα αποτελέσματα της προσομοίωσης και τα αντίστοιχα θεωρητικά και αν ναι που οφείλεται αυτό; Προτείνατε τρόπους βελτίωσης. p n -11-