Laboratorul 2

Cuprins

  1. introducere în gnuplot
  2. introducere în awk
  3. comenzi utile în shell
  4. wireless ns-2

1. Introducere în gnuplot

Plotarea datelor 1) 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 \#):

data1
 # comentarii 
 # X Y
   1 2
   2 3
   3 2
   4 1

Poate fi plotat scriind:

set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 3.5
plot 'data1' with linespoints ls 1

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

Dacă avem colecții de puncte care reprezintă date ne-continue, putem indica aceasta prin introducerea unei linii libere între date

data2
 # data2
 # XY
   1 2
   2 3
 
   3 2
   4 1

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'.

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

Și plotăm cu comenzile:

# 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

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

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:

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

Vom plota astfel:

 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

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:

Putem evita comanda set format din ultimul grafic prin manipularea directă a datelor de intrare:

 set yrange [ 0:120 ]
 plot 'battery.dat' using 1:($2*1000):($3*1000)\
                    w yerrorbars ls 1

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, \
     'out.tr' using 1:3 t "UDP" with lines lw 3
set xlabel 'Time[s]'
set ylabel 'Bandwidth[Mbps]'
set grid ytics
set term png
set out 'lab02bw.png' 
replot
save 'lab02bw.plot'  # se va putea reface graficul cu gnuplot ./lab02bw.plot
</code>  {{:isrm:laboratoare:02:lab02bw.png?300|}}

=== 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.      
    * Î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:

trace.out
10 2    0.2
11 3 0.3
12 2 0.2
 
13 3 0.1
14 4 0.05 
  • cat trace.out | awk '{print $1+$2, $2 $3, i++;}'

    produce

    12 20.2 0
    14 30.3 1
    14 20.2 2
    0  3
    16 30.1 4
    18 40.05 5 
  • Din acest exemplu se observă că:
    • caracterul $ trebuie protejat de shell 
       * separatorul implicit este (tab|spațiu)+
       * variabilele sunt inițializate la 0, și își păstrează valoarea de la o linie la alta
       * câmpurile inexistente ale unei linii sunt șirul vid 
       * tipurile sunt slabe - int, float, string, din context  
       * spațiu este operator de concatenare pe stringuri
    * <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
13 3 0.1
5 0.17 </code> 
    * Din acest exemplu se observă că:
      * există variabile predefinite NF= number of fields(each line); NR=number of records; $0 = toată linia
    • se pot rula mai multe programe per linie, dacă sunt activate de condiții logice/regex. Pentru o linie se execută TOATE programele care se pot activa.
    • există secțiunea BEGIN{} care se rulează o singură dată înainte de input, și END{} la sfârșit
    • sunt disponibile multe funcții de bibliotecă: printf, sqrt, substr, xor - vedeți man awk

Exercițiul 2: În laboratorul 1, folosiți

$tcp attach [open tcp.tr w]
$tcp trace cwnd_
$tcp trace rtt_ 

pentru a explora relația dintre lungimea cozii la bottleneck (link n2 n3), RTT-ul perceput de TCP, și fracțiunea de debit obținută în concurență cu UDP.

  • Rulați pentru valori ale cozii: 5, 15, 50
  • De ce debitele obținute nu sunt stabile?
  • De ce apar debite UDP mai mari ca 1Mbps?
  • Care este relația dintre RTT și debite?

3. comenzi utile de shell

  • bash face toate calculele pe integer.
    $ x=5 
    $ echo $(($x / 3))
    1
  • $ awc() { awk "BEGIN{print $*}"; }
    funcția poate fi adăugata la .bashrc
    $ awc "$x / 3"
    1.66667
  • este necesar adesea să rulăm o buclă de pe linia de comandă
    $for i in `seq 10 2 20`; do awc "$i / 10"; done 
    1
    1.2
    1.4
    1.6
    1.8
    2
    $
  • în multe cazuri se lucrează direct de la prompt pentru a pregăti datele de plotat
  • script one liner foarte des folosit în majoritatea laboratoarelor, datele vor fi pe ecran și în fișierul “out.a”
    $ 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
    $
    • 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 ns2 wireless tutorial

Marc Greis tutorial secțiunea IX .

  • Exemple de linii din trace cu newtrace:
    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 
    d -t 1.804824308 -Hs 2 -Hd 2 -Ni 2 -Nx 75.00 -Ny 0.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw COL -Ma 13a -Md 2 -Ms 0 -Mt cbr -Is 0.0 -Id 2.1 -It cbr -Il 1590 -If 0 -Ii 144 -Iv 32 -Pn cbr -Pi 34 -Pf 0 -Po 0
  • Fiecare linie descrie un eveniment de trimitere, primire, dirijare, sau dropare a unui pachet. Câmpurile cele mai importante dintr-o linie a fișierului trace sunt:
    s: Send
    r: Receive
    d: Drop
    f: Forward 
    
    -t 	double 	Time (* For Global Setting)
    -Ni 	int 	Node ID
    -Nx 	double 	Node X Coordinate
    -Ny 	double 	Node Y Coordinate
    -Nz 	double 	Node Z Coordinate
    -Ne 	double 	Node Energy Level
    -Nl 	string 	Network trace Level (AGT, RTR, MAC, etc.)
    -Nw 	string 	Drop Reason
    -Hs 	int 	Hop source node ID
    -Hd 	int 	Hop destination Node ID, -1, -2
    -Ma 	hexadecimal	Duration
    -Ms 	hexadecimal	Source Ethernet Address
    -Md 	hexadecimal	Destination Ethernet Address
    -Mt 	hexadecimal	Ethernet Type
    -P 	string 	Packet Type (arp, dsr, imep, tora, etc.)
    -Pn 	string 	Packet Type (cbr, tcp) 
    -Ps     sequence number (pentru tcp, coloana 47)

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 monitoriza evenimentele de la nivelele 2 și 4 (agent și MAC)
  • 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)? 2)
  • 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 3)
  • calculați numărul de cadre de date(tcp)pierdute de fiecare nod la nivelul 3 - IFQ 4)
  • justificați diferențele 5)
  • comparați pierderile între pachetele tcp și ack 6)
  • comparați pierderile între cadrele ACK și RTS 7)
  • justificați diferențele

Exercițiu 4 dezactivați RTS/CTS folosind

Mac/802_11 set RTSThreshold_    3000

ș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.

  •  cat simple.tr | grep '^r'  | grep AGT | grep tcp | grep -v ack | awk '{print $3, $47}' 
1) Ghid bazat pe Gnuplotting
2) cat simple.tr | grep '^r.*AGT.*ack.*tcp' | awk '{print \$3, \$47}'| head
3) cat simple.tr | grep '^d' | grep MAC | grep 'tcp' | grep -v 'ack' | wc -l
4) cat simple.tr | grep '^d' | grep IFQ | grep 'tcp' | grep -v 'ack' | wc -l
5) atenție, avem cadre ACK, tcp fără ack , tcp și ack. ACK sunt confirmări 802.11, ack sunt confirmări TCP. Se pierd 11 cadre TCP/date (linii cu tcp, dar fără ack) la nivelul 2, și 83 sunt aruncate din coadă. Dacă destinația nu mai răspunde în aer, 802.11 ajunge la maximum retries, apoi trece la următorul pachet. TCP însă nu trece mai departe după pierdere. Când destinația iese din zona de comunicare, TCP continuă să trimită deoarece are fereastră suficientă, și se pierde din coadă.
6) un ack se generează ca răspuns la un tcp. Dacă tcp sunt pierdute la transmisie (coadă sau aer), se generează mai puține ack
7) 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.
isrm/laboratoare/02.txt · Last modified: 2019/02/28 20:45 by mbarbulescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0