Documente Academic
Documente Profesional
Documente Cultură
Generarea Adreselor IP Folosind Arbori de Cautare LC
Generarea Adreselor IP Folosind Arbori de Cautare LC
I. Introducere.
1
In capitolul 2, vom trece in revista cautarea de adrese de IP. In capitolul 3, solutia noastra va
fi comparata cu ceea ce s-a publicat in domeniu. Capitolul 4 ne va da instrumentele necesare
pentru arborii LC impreuna cu structuri de date in codul C. Aceasta structura este aplicata pentru
organizarea rutarii de IP-uri din capitolul 5. Rezultatele tabelei de rutare din ruterele principale de
pe Internet sunt prezentate in capitolele 6 si 7. Capitolul 8 subliniaza tipuri generale de clasificari
de pachete pentru link sharing si metode elementare de rutare.
Un header de pachet pentru IP-4 este de 20 bytes lungime. Printre alte campuri, el contine
atat adresa calculatorului destinatie, cat si adresa calculatorului sursa. O adresa IP consta intr-un
identificator de retea si un identificator host. Rutarea se bazeaza numai pe identificatorul retelei.
La inceput, identificatorul de retea a avut o lungime pre-determinata indicata de un prefix aflat in
primii biti din identificator: 0 indicand o retea de clasa A cu 8 biti pentru identificarea retelei, 10
indicand clasa B, cu 16 biti, 110 indicand clasa C cu 24 biti pentru identificare (1110 aflandu-se
in clasa D de adresare, care este folosita pentru trasmisii multiple).
O adresa IP poate fi impartita acum in 2 parti: in identificatorul retelei (tipul retelei) si
identificarea hostului. Identificatorul de retea este prefixul ce este stocat in tabela de rutare, si nu
este neaparat acelasi pentru aceeasi adresa in toate ruterele.
In principiu, pentru adresa 222.21.67.68 ne intoarce identificatorul de retea 222.21.64 cu un
prefix de lungime pe 18 biti si identificatorul 222.16 cu o lungime pe 12 biti. Cu o adresa care se
potriveste perfect cu aceste prefixe intr-un ruter va trebui rutata potrivit informatiei pastrata
pentru prefixul cu 18 biti.
Chiar daca adresele bazate pe clase nu se mai folosesc ele apar inca in tabela de routare.
Figura 1 arata lungimea de la routerul principal din Mae East. Sunt varfuri de semnale pronuntate
de lungime 24, si la un grad mult mai mic, de lungime 16 (inainte adrese de clasa C si B).
Prefixele de lungime mai mica de 16 bits sunt rare si pot fi extinse la 16 biti. Deci, prima
comparatie a unei adrese cu prefixele pastrate poate fi bazata pe primii 16 biti ai adrese, ceea ce
ar reduce considerabil lungimea arborelui de cautare. Odata cu redistribuirea adreselor IP, putem
sa ne asteptam la o distribuire mai lina fara varfuri de semnale pronuntate. In studiul nostru,
aratam rezultatele atat pentru o schema cu 16 biti de comparatie la primul nivel in arbore cat si
pentru o schema completa. Resultatele sunt comparabile in termeni de numar de cautari ai
adreselor.
Cele mai multe routere au prestabilit un drum de routare care este dat de un prefix de
lungime 0 si de aceea se potriveste cu toate adresele. Ruta prestabilita este folosita deseori daca
nici un prefix nu se potriveste. Este nevoie de principalele routere din internet pentru a recunoaste
toti identificatorii si nu se poate folosi o ruta prestabilita. Consecinta este ca tabelele de adrese ale
acestor routere tind sa fie mai mari decat cele din celelalte routere. Am folosit tabele din routerele
principale in evaluarea noastra pentru a ne asigura ca testam cu date realiste.
Chiar daca structura de adrese pentru IP ver. 6(IPv6) nu este completa inca si pentru
adresele unicast, sunt sugestii pentru pastrarea identificatorilor de retea de lungime variabila (sau
identificatori ai subretelelor, cum sunt numiti aici). Deci , o subretea poate fi identificata de, sa
spunem, m biti intr-un router, in timp ce bitii ramasi (128-m) ai identificatorului interfetei(care
inlocuiesc identificatorul clientului din versiunea 4) sunt ignorati. Structura noastra de date este
alcatuita astel incat sa rezolve si adresele IPv6, si prin urmare cu o crestere corespunzatoare a
spatiului.
Rezultatul unei cautari a adresei IP intr-un router este numarul portului si adresa
urmatorului nod care trebuie folosit pentru pachet. Adresa urmatorului nod este folosita pentru a
2
gasi adresa legaturii fizice (ex. Adresa Ethernet) pentru urmatorul router de banda atunci cand
interconectarea este printr-o retea cu mediu fizic comun.
Informatiile pentru urmatorul nod nu sunt de obicei necesare pentru legaturile puct-punct, si
corespunzator tabela de rutare va contine numai numarul portului de iesire. Chiar atunci cand este
nevoie de adresa urmatorului nod, sunt, de obicei, mai putine adrese distincte de acest fel decat
cate intrari in tabela de rutare. Prin urmare, tabela de rutare poate sa contina un puinter la un
vector care arata urmatoarea adresa folosita.
III.
3
IV.
Arborele [10] este o structura general valabila pentru stocarea sirurilor. Ideea este foarte
simpla: fiecare sir este reprezentat de o frunza a arborelui, si valoarea sirului corespunde
drumului de la radacina arborelui la capat. Sa luam un mic exemplu. Sirurile binare din Fig. 2
corespund arborelui din Fig. 3(a). In particular, sirului 010 corespunde drumului ce porneste de la
radacina si se termina in capatul cu numarul 3: intai o intoarcere la stanga (0), apoi la dreapta (1),
si in final o intoarcere la stanga (0). Pentru simplicitate, vom presupune ca setul de siruri ce vor fi
stocate in arbore nu au prefix; nici un sir nu poate fi un prefix al altui sir. Vom sari discutia despre
modul in care se reprezinta prefixele pana la sectiunea urmatoare.
Aceasta structura simpla nu este foarte eficienta. Numarul nodurilor poate fi mare si
adancimea media (media lungimii unui drum de la radacina la un capat) poate fi mare. Tehnica
traditionala pentru a rezolva aceasta problema este de a folosi o "compresia a drumului" cand
fiecare nod intern cu numai un copil este inlaturat. Desigur, trebuie cumva sa inregistram care
noduri lipsesc.
O tehnica simpla este sa retinem un numar in fiecare nod, numit "valoare de salt", care
indica cati biti au fost sariti pe drum. Un arbore binar cu drumuri arhivate este denumit deseori ca
un Arbore Patricia [12]. Versiunea unui arbore (Fig. 3(a)) cu compresia drumurilor, este
prezentata in Fig. 3 (b). Numarul total de noduri in arborele cu compresia drumurilor este exact
de 2n-1, unde n este numarul capetelor din arbore.
Proprietatile statistice ale structurii acestui arbore sunt foarte bine cunoscute [6], [20].
Pentru o distributie de clase mare, arhivarea drumurilor nu da o reducere asimptotica a mediei
adancimii. Chiar si asa, arhivarea drumurilor este foarte importanta in practica, dat fiind faptul ca
de obicei da o semnificanta reducere a dimensiunii.
Cineva s-ar putea gandi la arhivarea drumurilor ca o cale de a compresa parti ale arborelui
care sunt imprastiate. Compresia de nivel [1] este o tehnica recent introdusa pentru compresia
partilor dintr-un arbore care sunt foarte populate. Ideea este de a inlocui nivelul i cel mai mare al
arborelui binar cu un singur nod de gradul 2^i; aceasta inlocuire este executata recursiv in fiecare
subarbore. Versiunea cu compresie de nivel al arborelui Fig. 3(b), arborele LC, este prezentata in
Fig. 3 (c).
Pentru un exemplu aleator cu o functie de densitate care este limita de sus si in jos, media
asteptata a adancimii arborelui LC este O(log *n), unde log*n este o functie logaritmica,
log*n=1+log*(log n), daca n>1, si log*n=0, in celelalte cazuri. Din datele unui proces de tip
Bernoulli cu probabilitati specifice care nu sunt egale, media asteptata a adancimii este O(log log
n) [2]. Arborii necompresati si arborii cu drumuri arhivate au, in ambele cazuri, o medie a
adancimii O(log n) pentru aceste distributii.
A. Reprezentarea
Daca dorim sa ajungem la o eficienta promisa de aceste baze teoretice, este importanta
reprezentarea eficienta a arborelui. Implementarea standard a arborelui, unde un set de pointeri
copii sunt stocati in fiecare nod intern, nu este o solutie buna, deoarece are un spatiu ocupat foarte
mare. Aceasta ar putea fi o explicatie la faptul ca structurile arborescente sunt considerate a ocupa
multa memorie.
O alternativa eficienta din punct de vedere al spatiului este stocarea copiilor unui nod in
locatii de memorii consecutive. In acest fel, numai un pointer la cel mai din stanga copil este
necesar. In realitate, nodurile pot sa fie stocate intr-un vector, si fiecare nod poate fi reprezentatat
4
de un singur cuvant. In imprementarea noastra, primii 5 biti reprezinta factorul de dispersie,
numarul de descendanti al unui nod. Acest numar este intotdeauna o putere a lui 2, si de aici
folosind 5 biti, factorul maxim de dispersie care poate fi reprezentat este 2^31. Urmatorii 7 biti
reprezinta valoarea de salt. In acest fel putem reprezenta valori in gama de 0-127, care este
suficint pentru adresele IPv6. Aceasta lasa loc la 20 biti pentru pointerul la copilul cel mai din
stanga, si de aici, folosind aceasta reprezentare compacta a 32-bit, putem stoca cel putin
2^19=524288 siruri (de retinut ca cel mai mare tabela de adrese de acum contine aproximativ
50000 de inregistrari). Fig. 4 reprezinta o reprezentare a vectorilor unui arbore LC din Fig. 3(c);
fiecare inregistrare reprezinta un nod. Nodurile sunt numerotate in ordinea citirii pornind de la
radacina.Numarul din fiecare coloana cale reprezinta numarul bitilor folosind pentru dispersia
fiecarui nod. O valoare K>=1 arata ca respectivul nod are 2^K copii. Valoarea K=0 arata ca nodul
este un capat.
Urmatoarea coloana contine valoarea de salt, care este un numar de biti care poate fi sarit in
timpul unei operatii de cautare. Valoarea din coloana pointer are doua interpretari diferite. Pentru
un nod intern, este folosita ca un pointer la copilul cel mai din stanga; pentru un capat, este folosit
ca un pointer la baza vectorului continand sirul complet.
Algoritmul de cautare poate fi interpretat foarte eficient, ca in Fig. 5. Sa luam un sir s pe
care il cautam, si sa consideram o functie EXTRACT(p,b,s) care intoarce un numar dat de biti b
pornind de la pozitia p din sirul s. Vom nota vectorul reprezentand arborele cu T. Radacina este
stocata in T[0].
De tinut seama ca adresa intoarsa indica numai o posibila potrivire; bitii care au fost sariti in
timpul cautarii pot sa nu se potriveasca. De aceea, trebuie retinuta valuarea sirurilor separat si
realizarea unei comparatii pentru a verifica daca a fost executata cautarea cu succes.
Ca un exemplu, cautam sirul 10110111. Vom porni de la radacina, nodul 0. Observam ca
valoarea de dispersie este 3, si valoarea de salt este 0, si de aici vom extrage primii 5 biti ai sirului
de cautare. Acesti 5 biti au valoarea 5, care este adaugata la pointer, ducand la pozitionarea lui 6
in vector. In acest nod valoarea de dispersie este 2. Adaugand 2 la pointer, ajungem la pozitia 15.
In acest nod valoarea de dispersie este 0, care implica faptul ca este capat.
Valoarea pointerului este 5 si da pozitia sirului din vectorul de baza. De obeservat ca este
necesr sa verificam daca aceasta este o solutie adevarata. Trebuie sa comparam primii 5 biti ai ai
fiecarui sir de cautare cu primii 5 biti ai valorii sticate in vectorul de baza in pozitia indicata de
pointerul capat (10). De fapt, tabelul nostru (Fig. 2) contine un prefix 10110 care se potriveste cu
sirul, si cautarea a fost un succes.
B. Construirea arborelui
Construirea arborelui se face astfel. Primul pas, este sortarea vectorului de baza. Un
algoritm de sortare bazat pe comparare, cum este "quick sort" [1] este de obicei suficient. Daca
este dorita o viteza superioara, un algoritm "radix-sorting" [3] poate fi folosit.
Dat fiind verctorul de baza sortat, este usor de construit de sun in jos arborele LC, dupa cum
se arata in pseudocodul din Fig. 6. Aceasta procedura recursiva construieste un arbore LC
acoperind un subinterval al vectorului de baza. Acest subinterval este definit de primul membru
(primul), numarul sirurilor (n), si de lungimea prefixului comun (pre).
Mai departe, prima pozitie libera (pos) in vectorul care retine reprezentarea arborelui este
data ca argument procedurii. Sunt 2 cazuri. Daca intervalul contine numai un sir, pur si simplu
vom crea un capat; altfel, vom programa sarirea valorii caii respective (detaliile sunt discutate
mai incolo), creem un nod intern, si, in cele din urma, procedura este apelata recursiv pentru a se
construi subarborii.
5
Pentru a programa valoarea de salt, care este cel mai lung prefix comun al sirului din
interval, trebuie doar sa ne uitam la primul si ultimul sir. Daca acestea au un prefix comun de
lungime k, toate sirurile dintre ele trebuie, de asemenea, sa aiba acelasi prefix, deoarece sirurile
sunt sortate.
Factorul de dispersie poate fi programat si intr-un mod direct. Netind cont de prefixul
comun, verificam daca tuate cele 4 prefixe de lungime 2 sunt prezente (sunt cel putin doua ramuri
deoarece numarul sirurilor este cel putin 2, si inregistrarile sunt unice). Daca aceste prefixe sunt
prezente, vom continua cautarea prin verificarea faptului cdaca toate 8 prefixe de lungime 3 sunt
prezente.
Continuand aceasta cautare, vom gasi la un moment dat daca lipseste un prefix, si factorul
de dispersie va fi fixat.
Alocarea memoriei in vectorul care reprezinta arborele poate fi facuta simplu prin urmarirea
primii pozitii libere din acest vector. (In acest pseudocod, se presupune ca memoria a fost alocata
pentru nodul radacina inainte ca procedura sa fie apelata). O schema mai elaborata de alocare a
memoriei poate fi gasita.
De exemplu, in unele cazuri poate merita folosirea unei sablon de memorie care
optimizeaza comportarea memoriei cash a algoritmului de cautare pentru un tip de masina tipic.
Pentru a estima complexitatea timpului, observam ca procedura recursiva este apelata o data
pentru fiecare nod al arborelui. Programand valoarea de salt ia un timp constant. Factorul de
dispersie al unui nod intern este programata in timp proportional cu numarul de siruri din interval.
Similar, instructiunea de incrementare a ciclului este executata o data pentru fiecare sir din
interval. Asta inseamna ca fiecare nivel al arborelui poate fi construit in O(n) timp, unde n este
numarul total de siruri. De aici, in cel mai rau caz, complexitatea timpului este O(nh)+S, unde h
este inaltimea arborelui, si S este timpul necesar sortarii sirurilor. Folosind un algoritm de sortare
bazat pe comparare si presupunand ca sirurile au o lungime constanta, S=O(n log n). Cu un
algoritm de cautare de tip radix, putem ajunge la S=O(n) sub presupunerile de mai sus.
C. Optimizari ulterioare
6
V. Tabela de rutare
7
vectorul de urmatoarea oprire direct. Poate fi folosit cand un drum a fost urmat fara sarirea nici
unui bit din adresa, si deci o comparare cu sirul stocat in vectorul de baza nu este necesara.
Un acces la memorie ar fi astfel salvat pentru aceste adrese. In al treilea rand, inregistrarile
din vectorul de baza pot fi taiate prin stocare numai a modelelor care s-ar potrivi cu bitii care au
fost sariti in compresarea drumului, care tipic conteaza pentru o portiune mai mica din sirul
complet. De asemenea, cei doi pointeri ai urmatoarei opriri si ai prefixului pot fi reduse la unul si
doi octeti, respectiv. In al patrulea rand, putem aplica diferiti factori de umplere in diferite parti ai
arborelui pentru o arhivare relaxata de nivel pentru a da voie la o optimizare mai precisa intre
adancimea cautarii si marimea arborelui. Totusi, noi rezolvam numai ramificarea la radacina cu
16 biti, independent de factorul de umplere.
VI. Experimente
Solutia noastra este publica in totalitate, ca si codul sursa si datele. Masuratorile au fost
executate pe doua masini diferite: un server SUN Ultra Sparc II cu doua procesoare de 296 MHz
si 512 MB de Ram si un PC cu un procesor pentium la 133 MHz si 32 MHz Ram. Programele au
fost scrise in C si au fost compilate cu compilatorul gcc folosind optimizarea de nive -O4.
Folosim tabele de rutare date de masurarea performantelor de pe INternet si proiectul de
analizare. Am folosit tabele de rutare pentru Mae East si Mae West din 30 Octombrie 1997 si
AADS si Pac Bell din 24 August 1997.
Nu am avut acces la traficul actual care a fost rutat conform cu aceste tabele, si de aceea
traficul este simulat: pur si simplu folosim permutari aleatoare a tuturor intrarilor in tabela de
rutare. Inregistrarile au fost extinse la numere de 32 biti prin aduagarea de zerouri (aceasta nu ar
trebui sa afecteze masuratorile deoarece acesti biti nu sunt vizati de rutina de cautare). Am testat
de asemenea acest algoritm pe o tabela de rutare cu drumuri salvate a destinatiei actualea unui
pachet. Ruterul apartine FUNET.
Traficul real da rezultate mai bune decat destinatii generate aleator si depind de
dependentele din adresele de destinatie. Timpul a fost masurat in secvente de operatii de cautare,
unde fiecare cautare include extragerea adresei dintr-un vector, folosind cautarea in tabel,
accesarea tabelului cu urmatoarea oprire, si dand rezultatul unei varibile volatile.
Unele din inregistrari din tabelele de rutare contin mai multe urmatoare opriri. In acest caz,
prima listata a fost selectata ca adresa pentru urmatoarea-oprire pentru tabela de rutare, in timp ce
noi am considerat numai o adresa de urmatoare oprire pe inregistrare in tabela de rutare. Au fost
de asemenea putine inregistrari in tabela de rutare care nu contin o adresa de oprire urmatoare.
Aceste inregistrari au fost rutate la o adresa speciala de urmatoare oprire decat cele gasite in
tabela de rutare.
Tabelul I arata cateva masuratori a unui arbore LC cu factor de umplere 0.5 si folosind 16
biti de ramificatie la radacina. Acesta arata numarul intrarilor din tabela de rutare, numarul
adreselor urmatoarelor opriri, marimea structurii noastre de date, media arborelui, si numarul
cautarilor masurata in milioane de cautari/s. In implementarea curenta , o intrare in arbore ocupa
4 biti, in timp ce intrarile in vectorul de baza si prefixul vectorului ocupa fiecare 16 si 12 biti,
respectiv.Deci, marimea arborelui LC este mai mica decat 500 kB. Media traficului corespunzator
numarului de cautari/s se afla inmultinddu-l cu media dimensiunii pachetului, care este in jur de
25 biti.
De fapt, structura poate face fata la pete o jumatate de milion de cautari complete/s la un
calculator cu un procesor la 133MHz, si mai mult de 2M/s pe o mult mai puternica statie de lucru
8
SUN Sparc Ultra II. Aceste numere apartin ruterelor de baza din US si traficului generat aleator
fara dependente in adresa de destinatie.
Este interesant de retinut ca atunci cand se foloseste urmarirea traficului de la FUNET, timpul de
cautare este de doua ori mai rapid (cu 5 milioane de cautari/s pe statia SUN), chiar daca acest
arbore este si mai mare si mai adanc ca celelalte. Aceasta poate fi explicata prin locatia rutelor de
trafic. Cateva cautari apropiate unele de altele in arbore vor fi considerabil mai rapide datorita
schemei naturale de caching folosita de masina de calcul.
In cel mai rau caz timpul de cautare este legat de drumul maxim prin structura de cautare. In
experimentele noastre, adancimea maxima a arborelui LC este cel mult 5, in timp ce media
adancimii este tocmai sub 2.
In Fig. 7, numarul de cautari/s este punctat ca o functie a factorului de umplere. Cum era de
asteptat, traficul creste odata cu scaderea factorului de umplere, dar numai pana la un punct.
Folosind un factor de umplere foarte mic creaza o structura de date foarte mare care in schimb
adauga cereri mari pe mecanismul de cache al masinii respective, care rezulta in mod normal in
cautari mai incete. Totusi, folosind urmarirea traficului de la FUNET, mecanismul de caching
reuseste sa faca fata chiar unei structuri foarte mare cu o incetinire minora. De fapt, vom obtine
cel mai scurt timp de cautare folosind un factor de umplere de 0.05 chiar daca arborele ocupa 2.3
megabocteti de memorie.
Tabelul II ofera o descriere mai detaliata despre cum factorul de umplere influenteaza
structura de date. De retinut ca vom obtine reduceri dramatice atat in medie cat sin in adancimea
maxima cu numai o crestere mica in spatiu.
Singura optimizare si cea mai importanta este folosirea unui factor de dispersie mare la radacina.
Folosind 16 biti pentru ramificatie radacina formeaza o structura foarte eficienta, chiar si cu un
factor de umplere de 1. Principalul incovenient este ca marimea drumului maxim cautat este mare
in acest caz.
Nu a fost posibil sa facem o comparatie experimentala a structurii noastre de date cu alte
culte implementari extraordinare software, deoarece sursele de cod nu sunt accesibile public.
Totusi, o insperctie a algoritmilor arata ca toate aceste implementari au rutine simple de cautare si
realizeaza numai un numar mic de accesari ale memoriei in timpul unei operatii tipice de cautare.
De aici, credem ca performanta acestor algoritmi si a nostru sunt similare.De fapt, toti algoritmii
pornesc prin folosirea unei tehnici deseori denumita "bucketing". Primii 16 biti ai cautarii sunt
extrasi. (Spatiul adresei este impartit in 2^16 "grupe"). Pentru adresele actuale, aceste pas de
impartire, singur, aproapre rezolva problema rutarii. Acesta este ceea ce facem noi prin fixarea
ramificarii de la radacina a 16 biti indiferent de factorul de umplere.
Totusi, cu adrese mult mai aglomerate si cu introducerea IPv6, problema potrivirii
prefixelor nu mai poate fi rezolvata doar prin grupare. Arborele LC se adapteaza de asemenea
frumos situatiei respective. De fapt, nu sunt necesare schimbari in structura arborelui pentru a
putea fi folosit sirurilor de 128 biti din IPv6. Acelasi cod poate fi folosit. Numai dimensiunea
vectorului de baza, care este accesat doar o singura data, va creste.
De asemenea, de retinut ca marginile teoretice ale arborelui arata ca adancimea medie, care
este O(log log n) pentru o clasa mare de distributii, nu creste ca o functie a lungimii sirurilor, dar
numai ca o functie a numarului acestora. Mai departe, experimentele noastre arata ca timpul de
cautare pentru rutele de trafic este mic, chiar si in tabelele mari. Mecanismul normal de caching
functioneaza bine. De aici, ne asteptam ca arborele LC sa fie o structura de date competitiva
pentru urmatoarea generatie de rutere de asemenea.
VIII. Concluzii
9
Am demonstrat cum tabela de rutare pentru IP-uri poate fi succint reprezentata si eficient
cautata intr-un arbore LC. Structura noastra de date este succint reprezentata si eficient cautata in
arborele LC. Singura prezumtie este aceea ca o adresa este cuvant binar. Crescand marimea
acestui cuvant de la 32 biti la 128, nu va afecta toata structura principala de date.
Media adancimii cautarii creste foarte incet. Acesta este in principiu in concordanta cu
rezultatele teoretice. Un ruter poate executa pana la 5 milioane de cautari/sec, care corespunde
unei medii de trecere de 10Gb/sec.
10