This shows you the differences between two versions of the page.
isrm:laboratoare:02 [2016/09/29 18:57] dragos.niculescu |
isrm:laboratoare:02 [2019/02/28 20:45] (current) mbarbulescu |
||
---|---|---|---|
Line 1: | Line 1: | ||
==== Laboratorul 2 ==== | ==== Laboratorul 2 ==== | ||
+ | Cuprins | ||
+ | - introducere în gnuplot | ||
+ | - introducere în awk | ||
+ | - comenzi utile în shell | ||
+ | - wireless ns-2 | ||
- | == Introducere în gnuplot == | ||
- | * [[ http://www.gnuplotting.org/plotting-data/ | introducere în gnuplot ]] | + | === 1. Introducere în gnuplot === |
- | * **Exercițiul 1** realizați folosind ''gnuplot'' graficul din laboratorul 1. Indicați semnificațiile axelor și legenda. Salvați imaginea în format ''png/svg'', și scriptul pentru restaurarea imaginilor. | + | |
- | * Exemplu<code> | + | Plotarea datelor ((Ghid bazat pe [[ http://www.gnuplotting.org/plotting-data/ | Gnuplotting ]])) rezultate din măsurători sau |
+ | simulări este probabil cea mai frecventă utilizare a programului | ||
+ | gnuplot. Gnuplot | ||
+ | are două moduri generale de funcționare - interactiv și script. În | ||
+ | modul interactiv, fiecare comandă este scrisa la promptul gnuplot, cu | ||
+ | posibilitatea de a folosi la sfârsit comanda save pentru a | ||
+ | salva comenzile într-un script. Un script scris manual, sau obtinut | ||
+ | cu save poate fi pasat ca parametru programului gnuplot | ||
+ | pentru a genera grafice. | ||
+ | |||
+ | Datele discrete de intrare corespund funcțiilor date | ||
+ | prin puncte. Avem nevoie de un fișier de date de intrare și de câteva | ||
+ | comenzi pentru a manipula datele. Vom începe cu plotarea de bază a | ||
+ | datelor simple și apoi vom analiza plotarea datelor cu erori. | ||
+ | |||
+ | == Date simple == | ||
+ | La început, vom analiza un fișier de date. Acesta poate fi un fișier text care c | ||
+ | onține datele ca coloane. Considerăm fișierul de date numit plotting\_data1.dat | ||
+ | ce conține ( gnuplot-ul ignoră liniile care încep cu diez \#): | ||
+ | <file txt data1> | ||
+ | # comentarii | ||
+ | # X Y | ||
+ | 1 2 | ||
+ | 2 3 | ||
+ | 3 2 | ||
+ | 4 1 | ||
+ | </file> | ||
+ | Poate fi plotat scriind: | ||
+ | <code gnuplot> | ||
+ | set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 3.5 | ||
+ | plot 'data1' with linespoints ls 1 | ||
+ | </code> | ||
+ | |||
+ | Aici setăm tipul de punct (pt) și dimensiunea punctului | ||
+ | (ps), și culoarea (lc) de utilizat. Pentru stilurile de puncte și linii disponibile, puteți să | ||
+ | rulați comanda **test** la promptul gnuplot. Imaginea rezultată este | ||
+ | {{ :isrm:laboratoare:02:gnuplot:plotting_data1.png?nolink |}} | ||
+ | |||
+ | Dacă avem colecții de puncte care reprezintă date ne-continue, putem | ||
+ | indica aceasta prin introducerea unei linii | ||
+ | libere între date | ||
+ | |||
+ | <file txt data2> | ||
+ | # data2 | ||
+ | # XY | ||
+ | 1 2 | ||
+ | 2 3 | ||
+ | |||
+ | 3 2 | ||
+ | 4 1 | ||
+ | </file> | ||
+ | |||
+ | {{ :isrm:laboratoare:02:gnuplot:plotting_data2.png?nolink |}} | ||
+ | |||
+ | Dacă dorim să folosim altă culoare pentru cel de-al doilea set de date | ||
+ | care este totuși în același fișier, putem introduce încă o linie | ||
+ | liberă. Apoi trebuie să indexăm blocul de date începând cu comanda 'index'. | ||
+ | |||
+ | <file txt data3> | ||
+ | # data3 | ||
+ | # Primul bloc de date (index 0) | ||
+ | # X Y | ||
+ | 1 2 | ||
+ | 2 3 | ||
+ | |||
+ | |||
+ | # Al doilea bloc de index (index 1) | ||
+ | # X Y | ||
+ | 3 2 | ||
+ | 4 1 | ||
+ | </file> | ||
+ | |||
+ | Și plotăm cu comenzile: | ||
+ | <code gnuplot> | ||
+ | # albastru: | ||
+ | set line style 1 lc rgb '# 0060ad' lt 1 lw 2 pt 7 ps 3.5 | ||
+ | # roșu: | ||
+ | set line style 2 lc rgb '# dd181f' lt 1 lw 2 pt 5 ps 3.5 | ||
+ | plot 'data3' index 0 w lp ls 1 , \ | ||
+ | '' index 1 w lp ls 2 | ||
+ | </code> | ||
+ | |||
+ | Atenție, gnuplot dorește toată comanda pe o singură linie, de aceea poate fi necesar un backslash "\". | ||
+ | După cum putem vedea, am adăugat un alt tip de culoare și punct și am | ||
+ | reprezentat cele două seturi de date utilizând indexul și separat | ||
+ | parcelele cu o virgulă. Pentru a reutiliza ultimul nume de fișier, | ||
+ | putem folosi un nume vid \'\'. Rezultatul este | ||
+ | |||
+ | {{ :isrm:laboratoare:02:gnuplot:plotting_data2.png?nolink |}} | ||
+ | |||
+ | |||
+ | == Date cu erori == | ||
+ | |||
+ | O necesitate frecventă este reprezentarea datelor cu bare de erori | ||
+ | pentru a indica de exemplu comportarea funcției într-un punct. În | ||
+ | următorul exemplu avem măsurători ale puterii pentru o rezistență | ||
+ | dată, stocate în formatul: r, P, Perror care poate semnifica eroarea | ||
+ | de măsurare a puterii: | ||
+ | |||
+ | <file txt battery.dat> | ||
+ | # X Y stddev | ||
+ | 50.000000 0.036990 0.007039 | ||
+ | 47.000000 0.036990 0.007039 | ||
+ | 44.000000 0.038360 0.007053 | ||
+ | 41.000000 0.042160 0.007050 | ||
+ | 38.000000 0.043200 0.007018 | ||
+ | 35.000000 0.046900 0.007021 | ||
+ | 32.000000 0.048840 0.006963 | ||
+ | 29.000000 0.052000 0.006929 | ||
+ | 26.000000 0.055470 0.006947 | ||
+ | 23.000000 0.060000 0.006882 | ||
+ | 20.000000 0.064660 0.006879 | ||
+ | 17.000000 0.069600 0.006936 | ||
+ | 14.000000 0.079800 0.007080 | ||
+ | 11.000000 0.086920 0.007232 | ||
+ | 8.000000 0.085500 0.007262 | ||
+ | 5.000000 0.101260 0.008415 | ||
+ | 2.000000 0.091000 0.011203 | ||
+ | 0.000000 0.081480 0.011828 | ||
+ | </file> | ||
+ | |||
+ | Vom plota astfel: | ||
+ | <code gnuplot> | ||
+ | set xrange [ -2 : 52 ] | ||
+ | set yrange [ 0 : 0.12 ] | ||
+ | set format y '% .0s' | ||
+ | plot 'battery.dat' using 1:2:3 \ | ||
+ | w yerrorbars ls 1 , \ | ||
+ | '' using 1:2 w lines ls 1 | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Valorile puterii sunt stocate în Watt în fișierul de date, dar au | ||
+ | valori mai mici decât 1. De aceea dorim să folosim mW ca unitate de | ||
+ | măsură. Așadar, am setat opțiunea de format pentru a spune | ||
+ | gnuplot-ului să folosească "mantisa as base of current logscale", vezi | ||
+ | documentația gnuplot . Apoi, cu indicația **using**, se | ||
+ | specifică gnuplot ce coloane din fișierul de date ar trebui să | ||
+ | utilizeze. Deoarece vrem să plotăm eroarea puterii și puterea, avem nevoie de | ||
+ | trei coloane - 1,2, și 4. Folosind stilul de | ||
+ | plotare **yerrorbars** nu este posibilă combinarea punctelor cu o | ||
+ | linie. Prin urmare, adăugăm o a doua linie la comanda **plot** pentru a | ||
+ | combina punctele cu o linie. Acest lucru va rezulta în: | ||
+ | |||
+ | {{ :isrm:laboratoare:02:gnuplot:battery_data.png?nolink |}} | ||
+ | |||
+ | Putem evita comanda **set format** din ultimul grafic prin manipularea | ||
+ | directă a datelor de intrare: | ||
+ | |||
+ | <code gnuplot> | ||
+ | set yrange [ 0:120 ] | ||
+ | plot 'battery.dat' using 1:($2*1000):($3*1000)\ | ||
+ | w yerrorbars ls 1 | ||
+ | </code> | ||
+ | |||
+ | Atenție, sunt necesare paranteze în jurul | ||
+ | expresiilor pe coloană, iar numărul coloanei este indicat cu caracterul \$. | ||
+ | |||
+ | În ultimul grafic adăugăm date teoretice și o legendă: | ||
+ | <code gnuplot> | ||
+ | # Legendă | ||
+ | set key at 50,112 | ||
+ | set xlabel 'Resistance (ohm)' | ||
+ | set ylabel 'Power (mW)' | ||
+ | # Curba teoretică | ||
+ | P(x) = 1.53**2 * x/(5.67 + x)**2 * 1000 | ||
+ | plot 'battery.dat' using 1:($2*1000):($3*1000) \ | ||
+ | title "Power" w yerr ls 2 , \ | ||
+ | P(x) title 'Theory' w lines ls 1 | ||
+ | </code> | ||
+ | |||
+ | În general, legenda este activată cu comanda **set key**, iar poziția sa poate fi specificată prin **set key top left**, | ||
+ | etc. Puteți, de asemenea, să o setați direct la un punct așa cum am | ||
+ | făcut-o aici, pentru a avea suficient spațiu între legendă și | ||
+ | ticuri. Cuvântul cheie din titlu în comanda plot specifică textul | ||
+ | care va fi afișat în legendă. | ||
+ | |||
+ | {{ :isrm:laboratoare:02:gnuplot:battery.png?nolink |}} | ||
+ | |||
+ | |||
+ | * Alte comenzi utile gnuplot: | ||
+ | <code gnuplot> | ||
+ | set term png # setează terminalul într-un format | ||
+ | set out 'file.png' # va plota într-un fisier | ||
+ | set xrange [0:4] # domeniul funcției | ||
+ | set ytics 0.2 # axa y etichetată la 0.2 | ||
+ | test # afișează puncte/linii cu stilul default | ||
+ | replot # redesenează | ||
+ | help plot with # manual la prompt | ||
+ | save 'file.plot' # creează un script pt plotul curent | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | **Exercițiul 1** realizați folosind ''gnuplot'' graficul din laboratorul 1. Indicați semnificațiile axelor și legenda. Salvați imaginea în format ''png/svg'', și scriptul pentru restaurarea imaginilor. | ||
+ | * Exemplu<code gnuplot> | ||
plot 'out.tr' using 1:2 t "TCP" with lp, \ | plot 'out.tr' using 1:2 t "TCP" with lp, \ | ||
'out.tr' using 1:3 t "UDP" with lines lw 3 | 'out.tr' using 1:3 t "UDP" with lines lw 3 | ||
Line 17: | Line 216: | ||
</code> {{:isrm:laboratoare:02:lab02bw.png?300|}} | </code> {{:isrm:laboratoare:02:lab02bw.png?300|}} | ||
- | == Introducere în awk == | + | === 2. Introducere în awk === |
* AWK (K vine de la Kernighan) este mic, simplu, și rapid, spre deosebire de perl sau python. Nu poți face tot ce faci în perl/python, dar poți face foarte ușor multe taskuri de procesare de text. Are o sintaxă apropiată de C, dar preferă datele organizate pe coloane, ca foarte multe date în rețelistică: trace-uri de simulare, tcpdump, loguri, etc. Un mare avantaj este ca poate fi rulat direct de pe linia de comandă, fără a mai folosi un script separat - de multe ori apare într-un pipeline cu cat, sed, tr. | * AWK (K vine de la Kernighan) este mic, simplu, și rapid, spre deosebire de perl sau python. Nu poți face tot ce faci în perl/python, dar poți face foarte ușor multe taskuri de procesare de text. Are o sintaxă apropiată de C, dar preferă datele organizate pe coloane, ca foarte multe date în rețelistică: trace-uri de simulare, tcpdump, loguri, etc. Un mare avantaj este ca poate fi rulat direct de pe linia de comandă, fără a mai folosi un script separat - de multe ori apare într-un pipeline cu cat, sed, tr. | ||
- | * În cazul cel mai des întâlnit, se specifică un program care este rulat succesiv pentru fiecare linie de intrare: <code>cat trace.out | awk '{print $2}'</code> afișează coloana a doua a fiecărei linii. De exemplu, pentru acest fișier: <file txt trace.out> | + | * În cazul cel mai des întâlnit, se specifică un program care este rulat succesiv pentru fiecare linie de intrare: <code awk>cat trace.out | awk '{print $2}'</code> afișează coloana a doua a fiecărei linii. De exemplu, pentru acest fișier: <file txt trace.out> |
10 2 0.2 | 10 2 0.2 | ||
11 3 0.3 | 11 3 0.3 | ||
Line 26: | Line 225: | ||
13 3 0.1 | 13 3 0.1 | ||
14 4 0.05 </file> | 14 4 0.05 </file> | ||
- | * <code>cat trace.out | awk '{print $1+$2, $2 $3, i++;}'</code> produce <code> | + | * <code awk>cat trace.out | awk '{print $1+$2, $2 $3, i++;}'</code> produce <code> |
12 20.2 0 | 12 20.2 0 | ||
14 30.3 1 | 14 30.3 1 | ||
Line 40: | Line 239: | ||
* tipurile sunt slabe - int, float, string, din context | * tipurile sunt slabe - int, float, string, din context | ||
* spațiu este operator de concatenare pe stringuri | * spațiu este operator de concatenare pe stringuri | ||
- | * <code>cat trace.out | awk 'NF==3 { s+=$3; n++} /1[2-3]/{print $0} END{print n, s/n}'</code> produce <code> | + | * <code awk>cat trace.out | awk 'NF==3 { s+=$3; n++} /1[2-3]/{print $0} END{print n, s/n}'</code> produce <code> |
12 2 0.2 | 12 2 0.2 | ||
13 3 0.1 | 13 3 0.1 | ||
Line 51: | Line 250: | ||
/********************** | /********************** | ||
- | - Exercițiul 2: Folosind <code>set qfile [$ns monitor-queue $n3 $n4 [open queue.tr w] 0.1] | + | - Exercițiul 2: Folosind <code tcl>set qfile [$ns monitor-queue $n3 $n4 [open queue.tr w] 0.1] |
[$ns link $n3 $n4] queue-sample-timeout; </code> | [$ns link $n3 $n4] queue-sample-timeout; </code> | ||
plotați dimensiunea în pachete cozii pe link-ul de ieșire [[http://www.mathcs.emory.edu/~cheung/Courses/558-old/Syllabus/90-NS/trace.html#QMon | Formatul]] fișierului queue.tr | plotați dimensiunea în pachete cozii pe link-ul de ieșire [[http://www.mathcs.emory.edu/~cheung/Courses/558-old/Syllabus/90-NS/trace.html#QMon | Formatul]] fișierului queue.tr | ||
* {{:isrm:laboratoare:02:lab02qsize.png?300|}} | * {{:isrm:laboratoare:02:lab02qsize.png?300|}} | ||
************************/ | ************************/ | ||
- | - **Exercițiul 2**: În laboratorul 1, folosiți <code tcl>$tcp attach [open tcp.tr w] | + | |
+ | **Exercițiul 2**: În laboratorul 1, folosiți <code tcl>$tcp attach [open tcp.tr w] | ||
$tcp trace cwnd_ | $tcp trace cwnd_ | ||
$tcp trace rtt_ </code> | $tcp trace rtt_ </code> | ||
Line 65: | Line 265: | ||
* Care este relația dintre RTT și debite? | * Care este relația dintre RTT și debite? | ||
- | == ns-2 wireless == | ||
- | Citiți [[ http://www.isi.edu/nsnam/ns/tutorial/nsscript5.html | Marc Greis tutorial secțiunea IX ]]. | + | === 3. comenzi utile de shell === |
+ | * bash face toate calculele pe integer. <code bash> | ||
+ | $ x=5 | ||
+ | $ echo $(($x / 3)) | ||
+ | 1 | ||
+ | </code> | ||
+ | * <code bash> | ||
+ | $ awc() { awk "BEGIN{print $*}"; } | ||
+ | funcția poate fi adăugata la .bashrc | ||
+ | $ awc "$x / 3" | ||
+ | 1.66667 | ||
+ | </code> | ||
+ | * este necesar adesea să rulăm o buclă de pe linia de comandă <code bash> | ||
+ | $for i in `seq 10 2 20`; do awc "$i / 10"; done | ||
+ | 1 | ||
+ | 1.2 | ||
+ | 1.4 | ||
+ | 1.6 | ||
+ | 1.8 | ||
+ | 2 | ||
+ | $ | ||
+ | </code> | ||
+ | * în multe cazuri se lucrează direct de la prompt pentru a pregăti datele de plotat | ||
+ | * script one liner <color red>**foarte des folosit în majoritatea laboratoarelor**</color>, datele vor fi pe ecran și în fișierul "out.a" <code bash> | ||
+ | $ i=1; while [ $i -le 10 ]; do echo -n "$i "; ns ./script.tcl -rate0 "$(($i*100))Kbps"| grep Throughput |head -n1 | awk '{print $2}'; i=$(($i+1)); done | tee ./out.a | ||
+ | 1 505744.0 | ||
+ | 2 989296.0 | ||
+ | 3 1495040.0 | ||
+ | 4 2026480.0 | ||
+ | 5 2504192.0 | ||
+ | 6 3004096.0 | ||
+ | 7 3143088.0 | ||
+ | 8 3120896.0 | ||
+ | 9 3118560.0 | ||
+ | 10 3124400.0 | ||
+ | $</code> | ||
+ | * atenție la spațiile de lânga parantezele drepte, și de lângă do, done. atenție la ; după fiecare comandă; înainte de do, done | ||
+ | * ''echo -n'' nu printează un CR la sfârsitul liniei, util pentru a ține un experiment pe o linie | ||
+ | * ''ns ./script.tcl'' produce un output de tipul ''Throughput 505744.0 bps'' din care reținem cu **awk** doar câmpul 2 | ||
+ | * ''head -n1'' reține doar prima linie de Throughput | ||
+ | * comanda ''tee'' lasă outputul pe ecran, dar îl salvează și în fișierul **out**, gata de plotat | ||
+ | |||
+ | |||
+ | === 4. wireless ns-2 === | ||
+ | |||
+ | Citiți [[ http://www.mathcs.emory.edu/~cheung/Courses/558-old/Syllabus/90-NS/4-Wireless/intro.html | ns2 wireless tutorial ]] | ||
+ | |||
+ | [[ http://www.isi.edu/nsnam/ns/tutorial/nsscript5.html | Marc Greis tutorial secțiunea IX ]]. | ||
+ | |||
* Exemple de linii din trace cu newtrace:<code> | * Exemple de linii din trace cu newtrace:<code> | ||
r -t 0.016905500 -Hs 1 -Hd -2 -Ni 1 -Nx 0.00 -Ny 75.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw --- -Ma 0 -Md 1 -Ms 0 -Mt ACK | r -t 0.016905500 -Hs 1 -Hd -2 -Ni 1 -Nx 0.00 -Ny 75.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw --- -Ma 0 -Md 1 -Ms 0 -Mt ACK | ||
Line 97: | Line 345: | ||
* detaliu http://www.isi.edu/nsnam/ns/doc/node186.html | * detaliu http://www.isi.edu/nsnam/ns/doc/node186.html | ||
- | - Exercițiul 3: modificați ''simple-wireless.tcl'' din Marc Greis sec IX pentru | + | **Exercițiul 3**: modificați ''simple-wireless.tcl'' din Marc Greis sec IX pentru |
* a utiliza noul format de trace ( cu ''$ns_ use-newtrace'') | * a utiliza noul format de trace ( cu ''$ns_ use-newtrace'') | ||
- | * a monitoriza evenimentele de la nivelele 2 și 3 | + | * a monitoriza evenimentele de la nivelele 2 și 4 (agent și MAC) |
* a avea o coadă de doar 10 pachete în interfața wireless | * a avea o coadă de doar 10 pachete în interfața wireless | ||
+ | * identificați în trace cadrele de tip CTS, ACK, ack, tcp. | ||
+ | * la ce moment începe transferul propriuzis (nodurile sunt suficient de aproape pentru a schimba cadre)? ((cat simple.tr | grep '^r.*AGT.*ack.*tcp' | awk '{print \$3, \$47}'| head )) | ||
+ | * Desenați o diagramă cu transferul unui segment TCP între noduri, indicând tipurile cadrelor/pachetelor. | ||
* calculați numărul de cadre de date(tcp)pierdute de fiecare nod la nivelul 2 - MAC (( cat simple.tr | grep '^d' | grep MAC | grep 'tcp' | grep -v 'ack' | wc -l)) | * calculați numărul de cadre de date(tcp)pierdute de fiecare nod la nivelul 2 - MAC (( cat simple.tr | grep '^d' | grep MAC | grep 'tcp' | grep -v 'ack' | wc -l)) | ||
* calculați numărul de cadre de date(tcp)pierdute de fiecare nod la nivelul 3 - IFQ (( cat simple.tr | grep '^d' | grep IFQ | grep 'tcp' | grep -v 'ack' | wc -l)) | * calculați numărul de cadre de date(tcp)pierdute de fiecare nod la nivelul 3 - IFQ (( cat simple.tr | grep '^d' | grep IFQ | grep 'tcp' | grep -v 'ack' | wc -l)) | ||
Line 112: | Line 363: | ||
* comparați pierderile între cadrele ACK și RTS (( ACK=0 pierderi, RTS=14 pierderi. Dacă nodurile sunt în apropiere, conversația RTS-CTS-Date-ACK se desfășoară cu bine, nu se pierd ACK-uri. La distanță mare, destinația nu răspunde la RTS, deci sunt pierdute, și nu se mai ajunge la ACK.)) | * comparați pierderile între cadrele ACK și RTS (( ACK=0 pierderi, RTS=14 pierderi. Dacă nodurile sunt în apropiere, conversația RTS-CTS-Date-ACK se desfășoară cu bine, nu se pierd ACK-uri. La distanță mare, destinația nu răspunde la RTS, deci sunt pierdute, și nu se mai ajunge la ACK.)) | ||
* justificați diferențele | * justificați diferențele | ||
- | - dezactivați RTS/CTS folosind <code>Mac/802_11 set RTSThreshold_ 3000</code> și comparați performanța TCP cu cazul precendent. Sugestie: plotați evoluția în timp a numerelor de secvență ((Numărul de secvență în timp este de fapt throughput. RTS-CTS introduce un overhead, de fapt timp pierdut, care duce la un throughput redus. )) | + | |
- | * <code> cat simple.tr | grep '^r' | grep AGT | grep tcp | grep -v ack | awk '{print $3, $47}' </code> | + | **Exercițiu 4** dezactivați RTS/CTS folosind <code>Mac/802_11 set RTSThreshold_ 3000</code> și comparați performanța TCP cu cazul precendent. Sugestie: plotați evoluția în timp a numerelor de secvență. Numărul de secvență în timp este de fapt throughput. RTS-CTS introduce un overhead, de fapt timp pierdut, care duce la un throughput redus. |
- | * {{:isrm:laboratoare:02:lab02tcp_rts.png?300|}} | + | * <code bash> cat simple.tr | grep '^r' | grep AGT | grep tcp | grep -v ack | awk '{print $3, $47}' </code> |
+ | * {{:isrm:laboratoare:02:lab02tcp_rts.png?300|}} |