Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Gestionarea memoriei

calculatoare



+ Font mai mare | - Font mai mic



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



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1561
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved