CATEGORII DOCUMENTE |
Gestionarea memoriei
1. Suprapuneri ( Overlays )
In cazul in care este necesar ca intreg spatiul logic de adrese al procesului sa se afle
in memoria fizica inainte ca acesta sa fie lansat in executie, dimensiunea programului va fi limitata de dimensiunea memoriei fizice. Pentru a permite unui program sa aiba o dimensiune mai mare decat a memoriei ce ii poate fi alocata se foloseste uneori o tehnica numita suprapunere ( overlay ). Ideea de baza este de a pastra in memorie numai acele instructiuni si date de care este nevoie permanent. Celelalte grupuri de instructiuni sunt incarcate si evacuate in/din o zona de memorie folosita in comun, numai atunci cand aceasta operatie este necesara.
Ca exemplu, se considera cazul unui asamblor in doua treceri: pe durata primei treceri se construieste o tabela de simboluri, iar pe durata celei de-a doua treceri se genereaza cod in limbaj masina. Gruparea instructiunilor se poate realiza astfel: codul
asociat trecerii 1, codul asociat trecerii 2, tabela de simboluri si rutinele utilizate in comun
de catre ambele treceri.
Trecerea 1 8 k Trecerea 2 10 k Tabela de simboluri 14 k Rutine comune 5 k
Incarcarea tuturor acestor elemente necesita 37 k de memorie si daca, de exemplu, nu avem la dispozitie decat 32k, programul nu va putea fi lansat in acelasi timp. Poate fi deci definit un driver de suprapuneri ( 2k ) care sa gestioneze memoria cu referire la existenta a doua module de program, incarcate succesiv, in acelasi spatiu: ( A ) tabela de simboluri, rutinele comune, trecerea 1 si ( B ) tabela de simboluri, rutinele comune si trecerea 2. In momentul incheierii executiei trecerii 1 ( modulul A ) are loc un salt la adresa drive-ului care determina aducerea in memorie a modulului B, suprainscriind A si apoi transfera controlul trecerii 2. Modulul A ocupa 29 K, in timp ce B are nevoie de 31 K, deoarece spatiul de memorie disponibil este de 32K, executia asamblorului este posibila. Codurile asociate lui A si B pot fi pastrate pe disc magnetic sub forma de imagine memorie absoluta
si sunt citite de catre driverul de suprapuneri ori de cate ori este necesar ( executia va fi mai lenta datorita operatiilor de I/O suplimentare ).
Pentru realizarea suprapunerilor nu este necesar ca sistemele de operare sa contina functii speciale, implementarea acestor metode de gestiune a memoriei, care presupune folosirea unor algoritmi specializati pentru relocare si inlantuire, poate fi realizata complet
de catre utilizator cu ajutorul fisierelor. Cu toate acestea, proiectarea si programarea corecta
a structurii modulelor ce vor fi suprapuse in memorie ramane o sarcina destul de complexa, care prespune o buna cunoastere a intregului program. Fiind vorba de programe de dimensiuni foarte mari ( programele de dimensiuni reduse nu necesita suprapuneri ), acest deziderat este destul de greu de realizat, motiv pentru care se prefera ca in locul metodei ce foloseste suprapuneri sa se utilizeze tehnici automate care sa permita executarea
programelor mari in cadrul unui spatiu de memorie limitat.
2 Incarcarea dinamica
Modulele de program ( rutinele, de exemplu ) sunt stocate in format relocatabil pe disc magnetic, programul principal se reincarca in memorie si se lanseaza in executie. In momentul in care se doreste apelarea unei rutine, se verifica mai intai ( cu ajutorul unor tabele de evidenta ) daca ea se afla in memorie. Daca nu, se apeleaza un program specializat
de incarcare cu relocatare si inlantuire care aduce in memorie rutina apelata, reactualizeza
tabelele in scopul inregistrarii acestei modificari si apoi cedeaza controlul noii rutine.
Avantajul incarcarii dinamice este ca rutinele sunt aduse in memorie numai in momentul in care sunt apelate, rutinele neutilizate nu vor fi incarcate niciodata. Aceasta metoda poate fi folosita, de exemplu, in cazul programelor de dimensiune mare care contin module voluminoase destinate tratarii unor situatii de eroare mai putin frecvente. Ca si in cazul metodei suprapunerilor, incarcarea dinamica nu impune existenta unor facilitati suplimentare in cadrul sistemelor de operare, intreaga raspundere a corectitudinii
functionarii revenind utilizatorului.
3. Gestionarea memoriei de catre sistemul de operare
Pentru un sistem dat, alegerea unei anumite metode de gestiune a memoriei depinde
de mai multi factori, dintre care proiectarea hardware a sistemului ocupa un loc foarte important. Algoritmii de gestionare a memoriei descrisi in cele ce urmeaza indeplinesc o
aceeasi cerinta de baza: pentru ca un proces sa poata fi lansat in executie trebuie ca mai intai
sa fie incarcat in memorie intregul sau spatiu de adresare logica, restrictie care limiteaza
dimensiunea unui progaram la dimensiunea memoriei fizice.
3.1. Monitor rezident
Una dintre primele metode de gestionare a memoriei folosite in cadrul sistemelor de operare timpurii este cea care grupeaza memoria in doua zone: una pentru utilizator si una pentru monitorul rezident al sistemului de operare. Monitorul rezident poate fi plasat in zona inferioara a memoriei, sau in cea superioara ( cu referire la valoarea adreselor ). Principalul factor care influenteaza aceasta decizie este in general localizarea vectorului intreruperilor; deoarece acesta se afla, de cele mai multe ori, in zona inferioara a memoriei, se prefera ca si monitorul rezident sa fie plasat in aceeasi zona.
Daca in sistem exista un singur program utilizator, protejarea codului si a datelor monitorului fata de modificarile accidentale sau intentionate pe care acesta i le-ar putea produce se poate realiza prin hardware, implementandu-se cu ajutorul unei scheme cu registru limita inferioara; folosirea unui registru limita superioara nu este necesara, deoarece in memorie nu exista decat un singur utilizator.
In situatia in care se doreste modificarea dinamica a dimensiunii monitorului ( si deci
a locatiei limita inferioara ) in timpul executiei unui program, se pot folosi doua alternative ale schemei de baza.
Prima metoda consta in incarcarea programului utilizator incepand din zona superioara a memoriei, spre zona limita inferioara ( in loc de a se realiza incarcarea in sens invers ( Figura 13 ) ); principalul avantaj este ca spatiul neutilizat va ramane in zona din mijloc a memoriei, unde, daca este necesar, atat programul utilizator, cat si monitorul se vor putea extinde.
A doua metoda, mai generala, consta in amanarea operatiei de asociere a adreselor pana in momentul executiei; schema de relocare dinamica necesita un suport hardware usor diferit ( Figura 14 ). In acest caz, registrul limita inferioara se numeste registru de relocare sau de baza; modificarea adresei de inceput a memoriei ce gazduieste programul utilizator
se poate realiza in orice moment si consta in schimbarea valorii registrului de baza si
deplasarea intregii zone utilizator la locatiile corecte in raport cu noua valoare. Programul utilizator lucreaza cu adrese logice cuprinse in domeniul "0" - "maxim", conversia acestora
in adrese fizice din domeniul "R + 0" - "R + maxim", in care R este valoarea limita
inferioara, fiind realizata de catre hardware-ul folosit pentru asocierea tabelata a adreselor
de memorie.
Figura 13 Figura 14
3.2. Multiprogramare cu partitii fixate
Intr-un sistem cu multiprogramare, este necesar ca memoria sa poata fi alocata in mod eficient numeroaselor programe aflate in rezerva de job-uri. Gestionarea cu partitii fixate fragmenteaza memoria intr-un numar de zone de dimensiune fixata, fiecare dintre acestea putand fi alocata cate unui program selectat dintre cele ce urmeaza a fi executate ( numarul de partitii limiteaza deci gradul de multiprogramare). In momentul incheierii executiei, partitia devine disponibila pentru incarcarea altui program.
Figura 15
Deoarece in memorie pot exista in acelasi timp mai multe programe, trebuie prevazute si mecanisme de protectie. Pentru fiecare partitie se pot folosi cite doi registri limita ( va fi necesara o relocare statica in momentul asamblarii sau al incarcarii) sau cate o pereche registru baza - registru limita ( solutia permite alocarea dinamica in momentul executiei ); registrul de baza contine valoarea celei mai mici adrese fizice, in timp ce registrul limita contine valoarea domeniului de adrese logice ( Figura 15 ).
Metode de planificare
Selectarea de catre planificator a unor job-uri aflate in rezerva pentru a fi incarcate in memorie se face in functie de necesarul de memorie declarat de acestea si de partitiile disponibile. In continuare vor fi prezentate cateva dintre strategiile folosite in acest scop.
O prima metoda este clasificarea tuturor job-urilor in functie de necesitatile de memorie, in momentul aparitiei lor in sistem; se creaza astfel cate o "coada" de job-uri pentru fiecare partitie. Clasificarea poate fi realizata pe baza informatiilor referitoare la necesarul maxim de memorie furnizate de catre utilizator sau determinate automat de catre sistem. Fiecare "coada" are propria partitie de memorie si va fi planificata separat ( nu apare concurenta intre "cozi" pentru accesarea memoriei). De exemplu, daca exista patru partitii
de memorie utilizator, de dimensiune 3K, 7K, 12K si 20K, vor exista patru "cozi", notate
C3, C7, C12 si C20 in care ar putea fi adaugat cate un job de dimensiune 2K, 7K, 10K si respectiv 19K.
O alta metoda este gruparea tuturor job-urilor intr-o singura "coada" din care planificatorul va selecta job-ul ce urmeaza a fi incarcat si apoi, pentru a realiza alocarea, va astepta pana in momentul in care devine disponibila o partitie de memorie cu dimensiune corespunzatoare. Daca planificatorul foloseste o strategie de tip FCFS ( First Come First Served ), este posibil ca un job sa fie nevoit sa astepte in "coada" chiar daca partitia ce-i este necesara este disponibila, numai pentru ca inaintea lui se afla job-uri cu necesar de memorie ce depaseste dimensiunile acesteia.
Ca o consecinta fireasca a acestei operatii a aparut o varianta de palnificare ce nu permite partitiilor de memorie sa stea nefolosite. Atunci cand o partitie devine disponibila se parcurge "coada" pana la ultimul job care ar putea fi cuprins in ea si se realizeaza alocarea, chiar daca in "coada" exista alte joburi mai prioritare, dar cu dimensiune mult mai mare. Acordarea permisiunii de alocare a unui job mai mic ( dar mai putin prioritar ) nu impiedica evolutia acestor job-uri care, oricum, nu puteau folosi partitia disponibila din cauza dimensiunii necorespunzatoare.
Metoda prezentata poate sa apara si in alte variante, in functie de strategiile de alocare a memoriei folosite:
Best Fit Only ( cea mai buna potrivire ); se aloca partitia cu dimensiunea cea mai apropiata de necesarul de memorie al job-ului; daca nu este disponibila, job-ul asteapta eliberarea ei;
Best Available Fit ( cea mai buna potrivire disponibila ); job-ului i se aloca prima partitie disponibila cu dimensiune suficient de mare ca sa il poata cuprinde.
Interschimbarea job-urilor ( Job Swapping )
Atunci cand in sistem exista mai multe job-uri cu dimensiune corespunzatoare unei aceleasi partitii, ele pot fi interschimbate ( introduse/evacuate in/din partitia respectiva ). Presupunand, de exemplu, ca se lucreaza cu trei partitii, pentru fiecare fiind folosit un algoritm de planificare de tip Round-Robin, in momentul epuizarii unei cuante programul de gestionare a memoriei va evacua job-ul curent si va introduce un alt job in partitia respectiva
( Figura 16 ) In timpul desfasurarii acestor operatii, planificatorul UC poate permite
executarea unui job din alta partitie. Pentru ca in memorie sa existe job-uri gata de executie
ori de cate ori actioneaza planificatorul UC, este de dorit ca programul de gestionare a memorie prin mecanismul descris anterior ( swapping ) sa lucreze cu o viteza adecvata.
Figura 16
In cazul algoritmilor de planificare bazati pe prioritati se foloseste o varianta a metodei prezentate anterior, numita Roll Out / Roll In: daca in sirul de planificare apare un job cu prioritate ridicata, programul de gestionare poate evacua un job mai putin prioritar, care va fi reintrodus in memorie si isi va continua executia numai dupa ce job-ul prioritar s-
a incheiat.
In mod normal, un job care a fost evacuat va fi readus in aceeasi partitie, restrictie impusa atat de strategia de alocare, cat si de metoda de relocare. Daca relocarea se realizeaza in momentul asamblarii sau in momentul incarcarii ( relocare statica ), job-ul nu poate fi transferat intr-o alta partitie, daca insa se lucreza cu relocare dinamica ( cu registru baza si registru limita, de exemplu ) acest lucru este posibil.
Interschimbarea job-urilor necesita o memorie externa cu acces direct, rapid, care sa
fie suficient de incapatoare pentru a putea ingloba copii ale tuturor imaginilor memorie utilizator (de obicei se foloseste in acest scop un disc magnetic performant). Toate procesele
ale caror imagini memorie se afla pe disc si care sunt gata sa intre in executie se grupeaza
intr-o "coada", in timp ce procesele existente in memorie la momentul respectiv formeaza o
"coada" sistem separata. Atunci cand planificatorul UC doreste sa lanseze in executie un proces, el apeleaza dispecerul care verifica daca procesul se afla in memorie. Daca nu, si daca nu exista nici o partitie libera, dispecerul evacueaza din memorie unul dintre procese,
introduce in locul sau procesul dorit, reincarca registrile si transfera controlul procesului selectat. Este important ca procesul ales pentru a fi evacuat sa fie inactiv, altfel pot sa apara eroari severe.
Intr-un sistem ce foloseste interschimbarea job-urilor timpul de comutare a contextului este ridicat. Pentru cresterea eficientei este de dorit ca timpul de executie al fiecarui proces sa fie mare in comparatie cu timpul necesar interschimbarii.
Job-uri cu dimensiune variabila
Exista situatii in care un program aflat in executie genereaza pe baza datelor de intrare cereri suplimentare de memorie. Daca datorita acestor cereri se depaseste dimensiunea partitiei alocate deja job-ului, sistemul de operare trebuie sa intervina. Exista trei posibilitati:
incheierea fortata a job-ului: se considera ca formularea unei cereri suplimentare fata
de maximul necesar declarat inainte de alocarea partitiei reprezinta o eroare de executie;
returnarea controlului programului utilizator cu un indicator de stare care sa specifice
ca nu exista memorie in plus ; programul utilizator va decide apoi daca se incheie imediat sau isi modifica modul de operare, astfel incat sa lucreze in spatiul
disponibil;
atunci cand exista hardware de relocare dinamica, se evacueaza job-ul, se asteapta eliberarea unei partitii cu dimensiune mai mare, se incarca job-ul in aceasta partitie ( relocandu-l daca este necesar ) si se continua executia; este o solutie destul de costisitoare, dar asigura flexibilitate maxima programelor care doresc sa-si modifice cerintele de memorie in functie de necesitati.
Stabilirea dimensiunii partitiilor
Principala problema a metodei de gestionare a memoriei ce utilizeaza partitii de dimensiune fixata este gasirea unei bune corespondente intre dimensiunile partitiilor si necesarul real de memorie al job-urilor. In proiectare, decizia initiala se bazeaza pe un calcul probabilistic. Din momentul in care sistemul devine operational se pot obtine informatii despre numarul si dimensiunea job-urilor ce se executa, pe baza carora sa se stabileasca apoi o structura a partitiilor mult mai apropiata de necesitatile reale. In general, nivelul de performanta al unui sistem de calcul depinde proportional de nivelul de multiprogramare care, la randul sau, este direct afectat de modul in care este gestionata memoria: daca, de exemplu, jumatate din spatiul total de memorie ramane neutilizat, inseamna ca folosind o metoda de gestionare mai buna ar fi posibil sa se execute de doua ori mai multe job-uri.
Fragmentarea memorie
Un job cu un necesar de memorie de x cuvinte se poate executa intr-o partitie de dimensiune y cuvinte, daca y>=x. Diferenta de ( y-x ) cuvinte reprezinta o fragmentare interna, adica o cantitate de memorie continuta in partitia alocata, dar neutilizata. In cazul in care o partitie este disponibila, dar prea mica pentru oricare dintre job-urile aflate in asteptare se spune ca in sistem exista fragmentare externa. Ambele tipuri de fragmentare genereaza risipa de memorie.
De exemplu, daca se separa o zona de 44K in trei partitii de cate 8K si o partitie de
20K, iar "coada" de planificare contine job-uri ce necesita 15K, 6K, 10K, 10K, partitia de
20K si una dintre partitiile de 8K pot fi alocate job-ului de 15K ( producand o fragmentare interna de 5K ) si respectiv, job-ului de 6K ( producand fragmentare interna de 2K ). Deoarece restul job-urilor sunt prea mari pentru cele doua partitii disponibile ( fiecare avand
cate 8K ), acestea raman neutilizate, generand o fragmentare externa de 16K. Fragmentarea totala, atat interna cat si externa, va fi de 23K, adica mai mult decat jumatate din intreaga memorie folosita in exemplu. Daca memoria este grupata in partitii de 20K, 8K, si 16K, job-
ul de 15K se poate executa in partitia de 20K, job-ul de 6K in partitia de 8K, iar unul dintre
job-urile de 10K in partitia de 16K, producand o fragmentare interna totala de 13K, dar eliminand fragmentarea externa. In cazul ideal in care dimensiunile partilor se potrivesc exact dimensiunilor job-urilor se pot executa toate cele patru job-uri fara fragmentare interna sau externa.
3.3. Multiprogramare cu partitii variabile
In cazul utilizarii metodei de multiprogramare cu partitii de dimensiune fixata, cea mai dificila problema este optimizarea dimensiunii partitiilor, astfel incat sa se minimizeze fragmentarea memoriei ( interna si externa ). Problema poate fi rezolvata daca se permite modificarea dinamica a marimii partitiilor. Initial, programele utilizator au la dispozitie intreaga memorie, considerata ca un bloc de dimensiune mare. Sistemul de operare genereaza si apoi reactualizeaza un tabel in care pastreaza informatii despre zonele libere si zonele ocupate ale memoriei. In momentul aparitiei unui job, se cauta o zona de memorie suficient de mare si, daca este gasita, se aloca job-ului numai dimensiunea ceruta, restul de memorie disponibila fiind pastrata pentru satisfacerea altor eventuale cereri.
In general, in memorie se afla "risipite" mai multe zone nealocate, de diferite dimensiuni. Atunci cand apare un job care necesita memorie, este aleasa una dintre acestea,
cu dimensiune suficient de mare pentru a satisface cerintele job-ului. Daca zona este prea mare, o parte se aloca job-ului, iar restul se reintegreaza setului de zone disponibile. In momentul terminarii executiei, job-ul elibereaza memoria aferenta, care va fi si ea inclusa in
set.
Daca zona de memorie disponibilizata este adiacenta celorlalte, ele se pot contopi pentru a forma o zona d dimensiune mare, moment in care se poate verifica daca nu cumva exista job-uri aflate in asteptare care ar putea folosi aceasta noua harta a memoriei. Aceasta situatie reprezinta un caz particular al problemei de alocare dinamica a memoriei ( care are
ca obiect modul in care se poate satisface o cerere de dimensiune precizata avand la
dispozitie o lista de zone de memorie disponibile ), pentru care exista mai multe variante de rezolvare. Cele mai utilizate strategii de selectare a zonei de memorie ce urmeaza a fi alocata sunt:
First Fit ( prima potrivire ): se aloca prima zona de memorie disponibila cu dimensiune suficient de mare pentru a satisface cerintele job-ului;
Best Fit ( cea mai buna potrivire ): dintre toate zonele de memorie disponibile a caror dimensiune permite alocarea job-ului, se alege zona cu cea mai mica dimensiune ( se minimizeaza fragmentarea interna );
Worst Fit ( cea mai proasta potrivire ): se aloca zona de memorie disponibila care are cea mai mare dimensiune.
La fel ca si in cazul utilizarii partitiilor fixate, metoda care foloseste partitii de dimensiune variabila se afla intr-o stransa interactiune cu planificarea job-urilor: exista o lista a dimensiunii zonelor de memorie disponibile si o "coada" in care se plaseaza job-urile
ce formuleaza cereri de memorie, ordonata conform algoritmului folosit de catre planificatorul de job-uri. Alocarea memoriei de desfasoara normal pana in momentul in care cerintele de memorie ale unui jub nu mai pot fi satisfacute doarece nu mai este disponibila nici o zona de memorie cu dimensiune suficient de mare. Planificatorul de job-uri va trebui
sa astepte eliberarea unei astfel de zone sau sa inspecteze "coada" pentru a gasi un job mai putin prioritar, al carui necesar de memorie sa poata fi satisfacut.
Suporul hardware minim necesar pentru implementarea metodei de gestiune a memoriei folosind partitii de dimensiune variabila este aceeasi ca si in cazul metodei ce utilizeaza partitii cu dimensiune fixa: doi registri in care sa se pastreze valorile adreselor limita superioara si inferioara ale partitiei de memorie alocate job-ului. Atunci cand planificatorul UC selecteaza procesul in vederea executiei, dispecerul incarca in registri valorile corespunzatoare si, deoarece fiecare adresa generata de catre UC este verificata prin comparatie cu continutul acestor registri, se asigura astfel protectia celorlalte programe utilizator si a datelor aferente fata de modificarile ce ar putea fi generate d catre procesul curent. De fapt, deosebirea dintre metoda cu partitii fixate si cea cu partitii variabile este determinata de catre software, hardware-ul fiind acelasi.
Fragmentarea memoriei
Metoda gestionarii memoriei prin folosirea partitiilor de dimensiune variabila prezinta dezavantajul existentei fragmentarii externe, aparute in momentul in care cantitatea totala de memorie disponibila este suficient de mare pentru a satisface o anumita cerere, dar
nu formeaza o zona contigua, ci este risipita in mai multe zone de mica dimensiune. Metoda gestionarii memoriei prin folosirea partitiilor de dimensiune variabila elimina insa aproape
complet fragmentarea interna ( se aloca numai atata memorie cata are nevoie job-ul ce trebuie planificat ). Cu toate acestea, daca zona disponibila este doar putin mai mare decat cea necesara, pastrarea evidentei celor cativa octeti ramasi nealocati ocupa mai multa memorie decat s-ar pierde prin alocarea si neutilizarea lor. De aceea, se prefera ca in acest caz sa se aloce intreaga zona, introducandu-se astfel, intr-o mica masura, fragmentare interna.
Compactarea
Compactarea reprezinta o metoda folosita pentru rezolvarea problemei fragmentarii
si consta in deplasarea continutului zonelor de memorie astfel incit sa se grupeze toate zonele libere intr-un bloc de dimensiune mare. Pentru ca programele ce formau continutul zonelor de memorie sa poata lucra la noile locatii trebuie relocate toate adresele interne.
Daca este vorba despre o relocare statica, compactarea nu poate fi facuta; ea este posibila
numai daca se foloseste relocare dinamica, la momentul executiei, folosind registri limita si
de baza ( in acest caz va fi necesara doar mutarea programului si a datelor si apoi inscrierea noii adrese in registrul de baza ).
3.4. Paginarea memorie
Paginarea este o metoda care rezolva problema fragmentarii in alt mod decat compactarea ei: ea permite ca memoria alocata unui program sa nu fie contigua, ceea ce inseamna ca programului ii poate fi alocata memorie oriunde exista si este disponibila.
Suportul hardware
Se considera ca memoria fizica ( atat cea interna cat si cea auxiliara ) este separata in blocuri de marime fixa numite cadre. Memoria logica este impartita in blocuri de aceeasi dimensiune numite pagini. Atunci cand se doreste lansarea in executie a unui program se transfera paginile sale din memoria auxiliara ( de obicei un disc magnetic cu acces rapid ) in oricare dintre cadrele disponibile ale memoriei interne. Fiecare dintre adresele generate de catre UC este formata prin alipirea a doua informatii: numnarul paginii ( p ) si deplasarea in pagina ( d ). Numarul paginii este utilizat ca index intr-o tabela de pagina care contine adresele de baza ale cadrelor asociate paginilor programului respectiv. Adresa de baza impreuna cu deplasarea in pagina definesc adresa fizica de memorie ce corespunde adresei logice generate de UC. Figurile 17 si 18 ilustreaza suportul hardware si respectiv modelul de memorie cu paginare ( paginarea memoriei logice si fizice ).
Figura 17
Figura 18
Dimensiunea in numar de cuvinte a paginii ( si a cadrului ) este definita prin hardware. Dimensiunea paginii este de obicei o putere a lui 2, ceea ce usureaza separarea adresei logice in cele doua componente: numar de pagina si deplasare. Daca marimea unei pagini este de 2n unitati de adresare ( octeti sau cuvinte ), atunci cei mai putini semnificativi
n biti ai adresei logice reprezinta deplasarea in pagina iar ceilalti biti, mai semnificativi, reprezinta numarul paginii.
Planificarea job-urilor
O particularitate deosebit de importanta a paginarii este distinctia foarte neta intre perceptia utilizatorului asupra memoriei si realitatea fizica a acesteia. Programul utilizator considera ca este unicul beneficiar al unui spatiu contiguu de memorie, in timp ce, de fapt,
el este risipit in mai multe zone distincte, alaturi de alte programe. Corespondenta intre spatiul de adresa utilizator ( logic ) si cel real ( fizic ) este realizata de catre hardware-ul de translatare a adresei ( de tabelare ), operatie controlata de catre sistemul de operare si invizibila pentru utilizator.
Pentru a putea gestiona memoria, sistemul de operare trebuie sa aiba la dispozitie informatii despre numarul total de cadre, cadrele alocate, cadrele disponibile etc., toate fiind pastrate intr-o structura de date numita tabela de cadre. Fiecare intrare a acestei tabele corespunde cate unui cadru al memoriei fizice, ingloband principalele sale caracteristici: este liber sau este alocat, procesul caruia ii este alocata si pagina asociata.
La fel ca si in celelalte cazuri, planificatorul de job-uri este influentat in mod direct
de catre metoda de gestionare a memoriei. Planificatorul de job-uri examineaza marimea job-ului ce urmeaza a fi executat ( exprimata in numar de pagini), dupa care inspecteaza
lista de cadre disponibile, tinand cont de faptul ca pentru memorarea fiecarei pagini
utilizator este necesar un cadru in memoria interna. In urma alocarii realizate de catre planificator, paginile se incarca pe rand in cadrele alocate, al caror numar va fi memorat in tabela de pagina al job-ului ( Figura 19-a - alocarea cadrelor libere inainte si Figura 19-b - alocarea cadrelor libere dupa ). Tabela de pagina asociata fiecarui job se pastreaza alaturi
de alte valori semnificative in blocul de control al job-ului.
Sistemul de operare pastreaza cate o copie a tabelei de pagina, a contorului program
si a continutului registrilor fiecarui program utilizator, informatii folosite si de catre dispecer
in momentul comutarii UC de la un proces la altul.
Figura 19 - a
Figura 19 - b
Fragmentarea memoriei
Paginarea elimina fragmentarea externa: unui job ii poate fi alocat orice cadru, cu conditia ca acesta sa fie disponibil. Deoarece cadrele nu sunt considerate unuitati de alocare
a memoriei ( se aloca in intregime, nu partial ), este insa posibila aparitia fragmentarii interne. Un exemplu in acest sens este situatia in care dimensiunea job-ului nu este un
multiplu exact al dimensiunii paginii si, prin urmare, ultimul cadru alocat nu este complet ocupat. In cel mai defavorabil caz un job poate fi format din N pagini si 1 cuvant, implicand alocarea a N+1 cadre, ceea ce va genera o fragmentare interna aproape egala cu dimensiunea cadrului.
Implementarea tabelei de pagina
In cazul in care dimensiunea tabelei de pagina este destul de redusa, se poate utiliza pentru implementare un set de registri specializati, foarte rapizi, care sa asigure o eficienta ridicata a translatarii adreselor ( eficienta este o cerinta foarte importanta deoarece orice acces la memorie se face numai prin intermediul tabelei de pagina ). Instructiunile destinate incarcarii sau modificarii acestor registri sunt privilegiate, putand fi realizate numai de catre sistemul de operare.
Daca insa dimensiunea tabelei de pagina este mare, se prefera ca ea sa fie pastrata in memoria principala, intr-o zona indicata de valoarea unui Registru de Baza al Tabelei de Pagina ( RBTP ). Atunci cand se doreste sa se lucreze cu alta tabela de pagina decat cea curenta, este suficient sa se incarce registrul cu o alta valoare, reducandu-se astfel in mod substantial timpul de comutare a contextului. O particularitate a acestei variante de implementare este faptul ca accesarea unui cuvant de memorie utilizator necesita doua operatii de acces la memorie ( unul pentru tabela de pagina si altul pentru cuvantul propriu-
zis ), viteza de operare fiind micsorata de doua ori. Folosind valoarea din RBTP deplasata
cu numarul de pagina - p ( continut in adresa logica ), se determina mai intai numarul de cadru - c asociat paginii ( pe durata unui prim acces la memoria ce contine tabela de pagina
). Numarul de cadru - c impreuna cu deplasarea de pagina - d ( continuta in adresa logica )
furnizeaza apoi adresa fizica reala, cu ajutorul careia se poate accesa cuvantul utilizator dorit.
O a treia varianta de implementare, care rezolva si problema expusa anterior, consta
in utilizarea unei memorii hardware speciale, rapide si de mica dimensiune ( set de registri asociativi ) cu urmatoarele proprietati: fiecare registru are doua componente, numite cheie,
si respectiv, valoare; precizandu-se un anumit element, el este comparat simultan cu toate cheile si, daca se depisteaza o coincidenta, se extrage campul valoare corespunzator. Daca
registri asociativi se folosesc impreuna cu tabelele de pagina, in cadrul campului cheie se memoreaza numarul de pagina iar in campul valoare, numarul cadrului asociat. Deoarece acest tip de hardware este destul de costisitor, numarul registrilor asociativi nu poate fi prea mare si, prin urmare, setul contine numai cateva dintre intrarile tabelei de pagina. Atunci cand UC genereaza o adresa logica, daca numarul de pagina coincide cu una dintre chei, numarul de cadru devine imediat disponibil si este folosit pentru a accesa memoria; timpul necesar pentru realizarea intregii operatii este cu cel mult 10% mai mare decat cel aferent
unui acces direct la memorie. Daca insa numarul paginii nu coincide cu nici una dintre chei, pentru obtinerea numarului cadrului asociat trebuie efectuat un acces la tabela de pagina aflata in memoria interna. Informatia astfel obtinuta va fi folosita atat pentru accesarea memoriei utilizator, cat si pentru a fi adaugata in cadrul registrilor asociativi ( impreuna cu numarul de pagina asociat ), ca sa poata sa fie regasita rapid in cadrul unei referiri ulterioare. Din punctul de vedere al timpului efectiv de acces la memorie, s-a demonstrat ca folosirea a 8 pana la 10 registri asociativi asigura o incetinire a operatiilor de memorie cu
aproximativ 20% pana la 10% fata de accesul direct, ceea ce constituie un avantaj in raport
cu performantele celei de-a doua variante de implementare prezentate.
Paginarea in sisteme de time-sharing
Unul dintre avantajele paginarii ( important mai ales in cazul sistemelor de tip time- sharing ) este posibilitatea folosirii in comun de catre job-uri diferite a unui acelasi cadru al memoriei fizice. Singura conditie este ca in acel cadru ( sau in acele cadre ) sa fie memorat cod reentrent ( numit si cod pur ), adica un cod care nu se poate modifica in timpul executiei. Datorita proprietatii de reentranta, este posibil ca doua sau mai multe procese sa execute simultan acelasi cod, fiecare proces pastrand o copie a registrilor si a datelor proprii
( care sunt diferite ). In memoria fizica este deci necesar sa se pastreze o singura copie a codului comun ( fiecare tabela de pagina indica spre acelasi/aceleasi cadru/cadre ), in timp
ce paginile corespunzatoare datelor proceselor sunt memorate in cadre diferite.
Exemplele de utilizare sunt numeroase: editoarele de texte, compilatoarele, asambloarele, sistemele de baze de date, sunt numai cateva dintre produsele software ce pot constitui cod folosit in comun, simultan, de catre mai multi utilizatori a unui sistem de tip time-sharing. Principalul avantaj al acestei metode este eliminarea risipei de memorie ( Figura 20 - accesarea in comun a codului in cazul paginarii ).
Figura 20
Cerinta de reentranta fiind stricta, codul folosit in comun trebuie sa fie accesibil numai pentru citire ( read only ), asigurarea acestei protectii fiind o sarcina a sistemului de operare. In general, protejarea paginilor se realizeaza prin asocierea unor biti de protectie,
inclusi in tabela de pagina. De exemplu, cu un singur bit se poate permite acces de citire/scriere sau doar de citire. Deoarece pentru fiecare referire a memoriei se foloseste tabela de pagina, odata cu calcularea adresei fizice se pot verifica si bitii de protectie. O incercare de scriere intr-o pagina marcata numai pentru citire, de exemplu, va genera o
"capcana" ( trap ) hardware catre sistemul de operare, avand semnificatia de a semnaliza violarea protectiei memoriei.
3.5. Segmentarea memoriei
De cele mai multe ori utilizatorul unui sistem percepe memoria nu ca pe o succesiune
de cuvinte ( asa cum este ea in realitate ), ci mai curand ca pe o colectie de zone contigue (
nu neaparat ordonate ) in care sunt stocate modulele componente ale programelor ( proceduri, functii, etc. ) si structurile de date aferente ( tabele, matrici, vectori, stive, variabile etc. ). Deoarece fiecare dintre module are o anumita functionalitate, de cele mai
multe ori zonele de memorie in care sunt stocate ( numite si segmente ) difera ca dimensiune si pot fi identificate prin nume: "functia pondere", "programul principal",
"matricea A", etc. In cadrul unui segment, un anumit element poate fi referit prin precizarea deplasarii fata de inceputul segmentului: "a treia instructiune a functiei Pondere", "prima instructiune a programului principal", "al doilea element al vectorului V", etc.
Segmentarea reprezinta o metoda de gestionare care accepta si foloseste aceasta viziune a utilizatorului asupra memoriei. Ea trateaza programul utilizator ( spatiul de adrese logice ) ca pe o colectie de segmente, fiecare segment fiind caracterizat prin nume si lungime. In consecinta, utilizatorul are obligatia de a preciza fiecare adresa logica prin doua elemente: un nume de segment si o deplasare ( in cazul paginarii, utilizatorul specifica adresa logica, separata apoi de catre hardware intr-un numar de pagina si o deplasare! ). De obicei, pentru simplificarea implementarii, se prefera numerotarea segmentelor si apelarea
lor prin numar, nu prin nume. De cele mai multe ori, segmentele sunt create in mod automat, in urma asamblarii, compilarii, etc. De exemplu, un compilator Pascal poate crea
segmente distincte pentru: variabile globale, stiva cu care lucreaza procedurile, codul fiecarei functii sau proceduri, variabilele locale ale fiecarei functii sau proceduri. Programul
de incarcare va asocia numere tuturor segmentelor astfel create.
Suportul hardware
Segmentarea implica existenta unei corespondente intre adresa logica bidimensionala definita de utilizator ( numarul de segmente - s si deplasarea in cadrul segmentului - d ) si adresa fizica unidimensionala ce ii este asociata in memorie. Aceasta corespondenta este realizata prin intermediul tabelei de segment ( Figura 21 ) care contine un numar de intrari egal cu numarul de segmente din programul respectiv. Fiecare intrare a tabelei contine informatii despre adresa de baza a segmentului ( notata "baza" in figura ) si despre dimensiunea acestuia ( notata "dim" in figura ) si poate fi accesata prin folosirea ca index a numarului de segment. Daca deplasarea precizata in cadrul adresei logice nu satisface relatia
0<d<dim, sistemul de operare va fi sesizat printr-o "capcana" cu semnificatia "incercare de adresare in afara segmentului". Daca insa deplasare se incadreaza intre limitele permise, valoarea ei se adauga la valoarea adresei de baza a segmentului, formandu-se astfel adresa din memoria fizica a cuvantului dorit ( se poate afirma deci, prin analogie, ca tabela de
segment este o colectie de perechi de registri baza/limita).
Figura 21
Figura 22
Pentru exemplificare se poate folosi situatia prezentata in Figura 22, care ilustreaza
dispunerea in memorie a unui program format din patru segmente ( numerotate de la 0 la 3
). Pentru fiecare dintre acestea , tabela de segment contine cate o intrare separata, in care se pastreaza adresa de inceput a segmentului in memoria fizica ( baza ) si dimensiunea segmentului ( dim ). Astfel, deoarece segmentul 1 incepe la locatia 1500 si are dimensiunea
500 de cuvinte, referirea cuvantului 25 al segmentului 1 corespunde in memoria fizica
locatiei 1500+25=1525, in timp ce referirea cuvantului 630 al aceluiasi segment va genera o
"capcana" catre sistemul de operare.
Implementarea tabelei de segment
Solutiile de implementare a tabelei de segment sunt asemanatoare celor folosite in cazul tabelei de pagina.
O prima varianta ( preferata pentru tabelele de segment de mici dimensiuni ) este utilizarea unor registri rapizi care sa asigure o viteza de acces foarte mare si, eventual, efectuarea simultana a operatiilor de comparare a deplasarii cu dimensiunea segmentului si respectiv a insumarii deplasarii cu adresa de baza a segmentului.
Atunci cand programul este format dintr-un numar mare de segmente se prefera ca tabela de segment sa fie pastrata in memorie. Pentru a putea fi accesata, se foloseste un registru baza al tabelei segment ( RBTS ) si, deorece programele nu contin acelasi numar de segmente, se utilizeaza in plus un registru lungime al tabelei de segment ( RLTS ). In acest caz, pentru fiecare adresa logica ( s,d ) se verifica mai intai corectitudinea numarului de segment ( 0<s<RLTS ) si apoi se insumeaza numarul segmentului cu continutul RBTS, rezultand astfel adresa din memorie a intrarii tabelei de segment ce va fi citita. Dupa aceea
se procedeaza in mod obisnuit: se compara deplasarea cu dimensiunea segmentului si se calculeaza adresa fizica a cuvantului dorit ca suma a deplasarii si a adresei de baza a segmentului.
La fel ca si in cazul paginarii, cea dea doua varianta de implementare a tabelei de segment necesita doua accese de memorie pentru o singura adresa logica, obligand sistemul
de calcul sa functioneze de doua ori mai incet. Solutionarea acestei probleme presupune folosirea unui set de registri asociativi in care sa se pastreze cele mei recent utilizate intrari
ale tabelei de segment. Un set destul de redus de registri asociativi ( 8 sau 16 ) poate asigura rezultate destul de performante: timpul de acces la memorie va fi doar cu cel mult 15% pana
la 10% mai mare decat in cazul accesului direct.
Segmentarea in sisteme de time-sharing
La fel ca si in cazul paginarii, segmentarea ofera atat posibilitatea folosirii in comun
de catre mai multi utilizatori a aceluiasi ( sau acelorasi ) segment(e) cat si asigurarea protectiei segmentelor cu ajutorul unor biti dedicati, inclusi in tabela de segment.
Ca exemplu, se poate folosi situatia in care un program contine segmente de instructiuni si segmente de date. Deoarece, in general, intr-o arhitectura moderna de calcul
nu este permis ca instructinile sa se automodifice, segmentelor de instructini li se pot asocia protectii care sa permita accesul doar pentru citire sau doar pentru executie. Verificarea bitilor de protectie este realizata de catre hardware in momentul efectuarii operatiilor de punere in corespondenta a adresei logice cu cea fizica. Se pot detecta astfel multe dintre
erorile de programare uzuale, inainte ca ele sa provoace neplaceri semnificative.
Pentru fiecare job, blocul de control ( folosit de catre dispecer in momentul comutarii UC intre procese ) contine alaturi de alte informatii si tabela de segment. Atunci cand intrarile in tabelele de segment apartinand unor job-uri diferite indica aceeasi locatie fizica, segmentul respectiv va fi folosit in comun ( mecanismul este asemanator cu cel prezentat in cazul paginarii ). Consecinta fireasca este ca orice informatie poate fi folosita in comun daca este definita ca segment. Deoarece acest mecanism functioneaza si pentru mai multe segmente, rezulta ca si programele ( colectii de segmente) pot fi la randul lor, folosite in comun de catre mai multi utilizatori ( aparenta simplitate a mecanismului ascunde si anumite subtilitati pe care programatorul este bine sa le cunoasca ).
Fragmentarea memoriei
Sarcina de a gasi si de a aloca memorie pentru toate segmentele programului utilizator revine planificatorului de job-uri. Situatia este asemanatoare cu cea aparuta in cazul paginarii, cu exceptia faptului ca aici lungimea segmentului este variabila ( paginile aveau toate acceasi dimensiune ). Aceasta inseamna ca este vorba despre o problema de alocare dinamica, la fel ca si in cazul metodei de gestionare a memoriei prin partitii cu dimensiune variabila, pentru a carei solutionare se pot folosi algoritmi de tip Best Fit sau First Fit.
Daca nici una dintre zonele contigue de memorie, disponibile la momentul considerat, nu este suficient de mare pentru a cuprinde un anumit segment, poate sa apara fragmentarea esterna. In general, daca dimensiunea medie a segmentelor este redusa, fragmentarea externa nu va fi semnificativa. Rezolvarea acestei probleme se realizeza cu aceleasi metode ca si in cazul gestionarii memoriei prin partitii cu dimensiune variabila.
Paginarea segmentelor
Atat paginarea cat si segmentarea au avantaje si dezavantaje. Acesta este motivul pentru care, uneori, s-a preferat combinarea celor doua metode de gestionare a memoriei prezentate anterior.
Un exemplu in acest sens este si paginarea segmentelor ( Figura 23 ), in cadrul careia se foloseste avantajul eliminarii fragmentarii externe oferit de catre paginare ( pentru alocare poate fi folosit oricare dintre cadrele disponibile ). Deosebirea dintre aceasta metoda
si segmentare este aceea ca intrare tabelei de segment nu contine adresa de baza a segmentului ci adresa de baza a unei tabele de pagina asociata acestui segment. Segmentul este format dintr-un numar de pagini de aceeasi dimensiune. Deplasarea in cadrul
segmentului se exprima prin numar de pagina si deplasare in pagina. Cu numarul de pagina
folosit ca index in tabela de pagina a segmentului, se obtine numarul cadrului care, in final,
se combina cu deplasarea in pagina si formeaza adresa fizica. Deoarece ultima pagina a fiecarui segment nu este intotdeauna complet ocupata, metoda introduce totusi o cantitate redusa de fragmentare externa ( in realitate, atunci cand se lucreaza cu tabele de segment de dimensiuni mari, mecanismul este ceva mai complicat ).
Figura 23
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1686
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved