Memorie virtuala

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Diagrama de operare a memoriei virtuale; în CPU programul funcționează ca și când ar avea disponibil un spațiu de memorie egal cu cel care poate fi adresat cu biții registrelor de adrese (de exemplu 4 GB cu registre pe 32 de biți); dar, în realitate, dacă memoria RAM este insuficientă, zonele de memorie utilizate în prezent (împărțite în pagini cu o dimensiune fixă) sunt alocate în RAM în timp ce paginile inactive sunt salvate într-un fișier gestionat de sistemul de operare de pe hard disk .

În informatică , memoria virtuală este o arhitectură de sistem capabilă să simuleze un spațiu central de memorie ( memorie primară ) mai mare decât cel prezent sau disponibil din punct de vedere fizic, oferind utilizatorului iluzia unei cantități enorme de memorie [1] .

Sistemul de operare, utilizând o combinație de hardware și software, mapează adresele de memorie utilizate de un program, numite adrese virtuale , în adrese fizice . Memoria principală , din punctul de vedere al unui proces, apare ca un spațiu de adrese contigu (sau o listă de segmente). Sistemul de operare gestionează spațiul virtual și alocarea memoriei fizice memoriei virtuale. Traducerea adreselor se face de către un hardware prezent în CPU , denumit în mod obișnuit MMU , care traduce diferitele adrese. Software-ul prezent în sistemul de operare poate extinde aceste caracteristici pentru a oferi spațiu virtual care depășește memoria memoriei fizice, adresând astfel mai multă memorie decât este prezentă fizic în computer.

Principalele avantaje ale acestei arhitecturi sunt securitatea mai mare datorită izolării memoriei, capacității de a partaja unele pagini de memorie între diferite procese (în special cea a bibliotecilor ) și posibilitatea de a utiliza mai multă memorie decât este disponibilă cu o tehnică numită swap .

Acest lucru se realizează prin utilizarea spațiului de stocare secundar pe alte dispozitive sau medii de stocare, de obicei unități de disc . Memoria centrală prezentă fizic devine apoi partea efectiv utilizată a celei virtuale, mai mare: această stratagemă este utilă în virtutea principiului localității și reutilizării execuției programului .

În mediul POSIX , memoria de masă utilizată în acest scop este denumită în mod obișnuit „ swap ” sau „ swap space” (verb în engleză care înseamnă „a schimba”), în timp ce, în mediul Windows, este denumită „fișier de paginare ”. Operațiunile de mutare a paginilor de la spațiul swap la memoria fizică se numesc „ swapping ”.

Descriere

Într-un sistem dotat cu memorie virtuală, procesorul și programele se referă la memoria centrală cu adrese virtuale logice , care sunt traduse în adrese fizice reale de către o unitate specială, MMU sau unitate de gestionare a memoriei care este în general încorporată în procesoare.

MMU îndeplinește următoarele sarcini:

  1. Traduce adresa logică în adresă fizică;
  2. Verificați dacă adresa fizică corespunde unei zone de memorie prezentă fizic în memoria principală;
  3. Dacă, pe de altă parte, zona în cauză se află în spațiul swap, MMU ridică o excepție de eroare de pagină și sistemul de operare o încarcă în memoria centrală, aruncând o pagină deja prezentă.

Acest mecanism are un preț în termeni de performanță: MMU durează ceva timp pentru a traduce adresa logică într-o adresă fizică și este nevoie de mult mai mult timp pentru a încărca o zonă de memorie din spațiul de swap: în cele din urmă, implementați o memorie virtuală înseamnă sacrificând puterea de calcul pentru a putea rula un număr mai mare de procese simultane.

T menționat un timp de acces normal la memoria fizică, T T timpul de translatare de adresă a MMU și T încărcați timpul necesar pentru a încărca o zonă de memorie din swap, (medie) timpul de acces în caz de memorie virtuală este:

T av = T t + T a + T sarcină * P defecțiune

unde defecțiunea P este probabilitatea unei defecțiuni a paginii , adică să ruleze într-o pagină care nu este prezentă în memoria principală și, prin urmare, trebuie să o încărcați din swap.

Mecanisme de memorie virtuală

Există în principal două moduri de a implementa un sistem de memorie virtuală: împărțiți memoria în multe pagini identice, gestionate de hardware sau lăsați programatorul și / sau compilatorul folosit de programator să „segmenteze” programul său în mai multe segmente (sperăm) independent.
Ambele metode prezintă avantaje și dezavantaje: în ultima vreme, însă, de departe cel mai utilizat sistem este memoria paginată, datorită omogenității și independenței mai mari față de software.

Memorie paginată

Cu această schemă, memoria este împărțită în pagini de aceeași dimensiune (4 sau 8 kiloocteți ): programele nu trebuie să știe nimic despre modul în care este organizată memoria și nu trebuie să aibă nicio structură internă specială; locația exactă și dispunerea fizică a memoriei pe care o ocupă nu le privește și întregul sistem de memorie virtuală este complet gestionat de MMU printr-un sistem complex de registre asociative. Tocmai acest sistem de registre este punctul slab al acestui tip de mecanism: dacă numărul de pagini este foarte mare (pagini mici sau cantități mari de memorie virtuală de emulat) mecanismul asociativ poate deveni prea complex, încetinind semnificativ accesul la memorie (și deci întregul sistem).

Un posibil remediu este creșterea dimensiunii paginilor de memorie, cu prețul unei risipi mai mari de memorie în sine („fragmentare internă”: cu cât paginile sunt mai mari, cu atât crește numărul de pagini parțial goale și se pierde mai mult spațiu) .

Mai detaliat, mecanismul de gestionare a memoriei virtuale cu paginare este următorul. Imaginea unei lucrări este împărțită în pagini cu o dimensiune fixă. Memoria principală (RAM) este, de asemenea, împărțită în „bucăți”, de aceeași dimensiune ca paginile, numite cadre de pagină. Fiecare proces este asociat cu un tabel, care este păstrat în memoria principală sau secundară în funcție de dimensiunea sa, numit tabel de pagini. Fiecare element (rând) din tabelul de pagini conține:

  • Numărul paginii pentru rândul respectiv;
  • Bitul prezent;
  • Bitul a fost modificat;
  • Numărul cadrului corespunzător.

Adresele logice sunt reprezentate de perechea (numărul paginii, offset). Traducerea are loc astfel: se găsește linia corespunzătoare numărului de pagină al adresei logice, dacă bitul prezent este 0, pagina nu este prezentă în memoria principală, se generează o eroare de pagină și pagina este încărcată în memorie, în cele din urmă se generează adresa fizică (număr cadru, offset)

Bitul modificat indică dacă pagina a fost modificată sau nu. De fapt, dacă o pagină nu a fost modificată, în momentul schimbării în memoria secundară, nu are sens să rescrieți paginile pe disc. Economisind astfel timp și îmbunătățind parțial performanța.

Un ultim detaliu tehnic. Să presupunem că avem adrese logice și fizice de lungime k biți. Dintre acestea n vor fi alocate n. em pagina pentru a compensa. Prin urmare, avem k = n + m. Din aceasta deducem că fiecare pagină și fiecare cadru au o dimensiune de 2 ^ m biți. Acum, să presupunem că, dacă dorim să traducem o adresă logică (numărul paginii, offset), vom constata că cadrul corespunzător paginii date este al i-lea. Cu toate acestea, acest lucru nu corespunde încă adresei fizice reale, ci doar indexului cadrului. Pentru a obține adresa fizică trebuie acum să înmulțim i * 2 ^ m. Avantajul acestei tehnici este că, în sistemul binar, această operațiune poate fi efectuată prin concatenarea m zerouri la reprezentarea binară a lui i. O operație foarte rapidă, care poate fi efectuată direct în hardware.

Memorie segmentată

În acest caz, mecanismul de memorie virtuală este parțial software. Programele care rulează pe sisteme cu memorie segmentată sunt structurate în segmente funcționale omogene: MMU urmărește care și câte segmente sunt prezente în memorie și unde. Principalul avantaj al acestui sistem este că folosește la maximum principiul localității menționat anterior, minimizând utilizarea spațiului swap: odată ce un program are segmentele de care are nevoie în memoria principală, va cere foarte rar altele noi. Dezavantajul semnificativ al acestui sistem, pe de altă parte, este risipa mare de memorie datorată fragmentării externe : odată cu trecerea timpului și succesiunea proceselor care rulează, memoria este alocată și repartizată în blocuri de diferite dimensiuni care lasă o un număr mai mare de "găuri" goale, prea mici pentru a fi alocate în mod util: acest lucru face necesară efectuarea unei compactări periodice costisitoare a memoriei fizice alocate și / sau utilizarea unor algoritmi de sofisticare foarte sofisticate.

Mai precis, mecanismul de gestionare a memoriei virtuale segmentate este după cum urmează. Un tabel de segmente este asociat cu fiecare proces; fiecare intrare din acest tabel reprezintă un segment al procesului și conține cel puțin următoarele câmpuri: bitul prezent, bitul modificat și adresa de bază a segmentului în memorie.

Adresele logice sunt reprezentate de perechea (numărul segmentului, deplasarea). Traducerea are loc în acest fel: găsiți intrarea din tabel corespunzătoare nr. segment; dacă bitul Prezent este 0, segmentul nu este prezent în memoria principală, prin urmare se generează o eroare de segment și se așteaptă ca segmentul să fie încărcat în memorie. În cele din urmă, adresa fizică este generată prin adăugarea deplasării la adresa de bază a segmentului din memorie.

Acces la hardware cartografiat cu memorie

Unele mecanisme hardware, cum ar fi DMA , necesită programul care le folosește pentru a citi și / sau a scrie pe pagini de memorie fizică bine determinate și nemobile. Pentru aceasta, schema de memorie virtuală a arhitecturilor care utilizează DMA implementează un mecanism de blocare a paginii cu care un program poate lega o serie de pagini contigue de memorie virtuală la o serie corespunzătoare de pagini contigue de memorie fizică; din motive evidente, paginile blocate cu acest mecanism nu sunt nici eliminate, nici mutate pentru a schimba spațiul.

Zdrobitoare

Este esențial ca cantitatea de memorie fizică prezentă să fie cel puțin suficientă pentru a menține localitatea sistemului, adică acea parte din date și informații care este utilizată imediat de fiecare proces. Dacă nu ar fi cazul, de fapt, sistemul ar trebui să efectueze în mod continuu operațiuni de schimb pentru a se asigura că fiecare proces are datele de care are nevoie.

De exemplu, să presupunem că la un moment dat memoria fizică este saturată și conține exact locația sistemului (adică suma tuturor „seturilor de lucru” ale proceselor procesate este exact egală cu memoria RAM fizică prezentă), și că în această situație va începe un nou program. Procesul creat trebuie să aloce ceva memorie. Cu toate acestea, deoarece memoria principală este plină, sistemul de operare eliberează o parte din spațiul stocat care face parte din informațiile din memoria secundară. Mai târziu, când controlul revine la procesul ale cărui date tocmai au fost mutate, este necesară o operațiune de swap-in pentru a reîncărca datele în memoria principală. Deoarece toate informațiile conținute în memoria principală sunt indispensabile, acest fenomen apare foarte des. Deoarece memoria secundară este mult mai lentă (de sute sau mii de ori) decât memoria principală, acest lucru determină o încetinire considerabilă a sistemului, care este angajat aproape exclusiv în operațiuni I / O și devine în curând inutilizabil și puțin sau deloc receptiv la utilizator comenzi. Acest fenomen se numește thrashing .

Din punct de vedere tehnic, atunci când memoria centrală liberă (RAM) (și, prin urmare, numărul de cadre libere) este insuficientă pentru a conține setul de lucru curent al unui proces, acesta din urmă va începe în curând să genereze mai multe defecțiuni de pagină, încetinind considerabil viteza de execuție. Când mai multe procese încep să bată, adică să petreacă mai mult timp paginând decât să ruleze, sistemul de operare poate induce în eroare pentru a deduce că este necesar să se mărească gradul de multiprogramare (având în vedere că CPU rămâne în cea mai mare parte timp inactiv datorită intensității I / O activitate). În acest fel, sunt demarate noi procese care, totuși, din cauza lipsei cadrelor libere, vor începe la rândul lor să intre în thrashing: pe scurt, performanța sistemului se prăbușește până când operatorul trebuie să încheie forțat unele procese. O modalitate de a limita acest fenomen este de a utiliza o procedură de înlocuire locală, adică de a oferi managerului de memorie virtuală posibilitatea de a înlocui paginile asociate singurului proces care le solicită. Acest lucru împiedică întregul sistem să bată.

Algoritmi de înlocuire a paginii

Există diverse tehnici pentru a decide ce zone ale memoriei trebuie mutate din stocarea primară în cea secundară. Următoarele sunt cele mai frecvente:

Strategie optimă

Pictogramă lupă mgx2.svg Același subiect în detaliu: algoritm optim .

Această tehnică constă în înlocuirea paginii de memorie care va fi reutilizată mai târziu. În mod clar, pentru a fi implementat cu adevărat, ar necesita ca sistemul de operare să cunoască din timp paginile folosite în viitor de procese. Prin urmare, nu poate fi folosit ca algoritm pentru înlocuirea paginilor din memoria principală, ci ca un indicator pentru compararea celorlalte strategii.

FIFO

Tehnica FIFO ( First In First Out ) este cea mai simplă, ține evidența într-un tabel a momentului în care a fost alocată o zonă de memorie. Când există o nouă cerere de alocare a paginilor de memorie, dacă mai există spațiu în memoria principală, noua pagină este pur și simplu alocată, altfel se consultă prin tabel ce pagini au fost alocate pentru cel mai mult timp și sunt mutate în memoria secundară .

Acest algoritm este foarte simplu și rapid de executat, dar are dezavantajul de a muta pagini mai vechi în memoria secundară, chiar dacă acestea sunt utilizate frecvent, produce și așa-numita anomalie Belady .

A doua alegere (algoritmul ceasului)

Există o simplă optimizare a tehnicii FIFO care elimină problema schimbării chiar și a paginilor foarte utilizate. Este suficient să adăugați un bit în tabel care ține evidența vechimii paginilor: de fiecare dată când sistemul de operare accesează o pagină, acesta setează acest bit la 1 în timp ce algoritmul de schimbare a paginii, dacă găsește bitul la 1, setează se mută la 0 și mută o pagină cu bitul deja setat la 0 în memoria secundară. În acest fel, paginile utilizate frecvent au o mare probabilitate de a rămâne în memoria principală.

În cel mai rău caz, toate paginile au bitul setat la 1, în acest caz algoritmul resetează toți biții până la revenirea la prima pagină luată în considerare. Găsindu-l acum cu bitul 0, îl înlocuiește. În acest caz, a doua substituție de alegere este redusă la o substituție FIFO.

Există o versiune modificată a următorului algoritm care are doi biți care urmăresc utilizarea și schimbarea. De fapt, există următoarele combinații:

  • (0,0): nici recent folosit, nici modificat - cea mai bună pagină de înlocuit
  • (0,1): Nu este folosit recent, dar modificat - trebuie rescris în memoria secundară înainte de a fi înlocuit
  • (1.0): folosit recent, dar nemodificat
  • (1,1): recent utilizat și modificat

Atunci când este necesar să efectuați o înlocuire a paginii, algoritmul caută mai întâi cea mai bună pagină de înlocuit, luând în considerare nu numai faptul că nu a fost folosit recent, ci și faptul că nu a fost modificată. De fapt, atunci când pagina a fost modificată, este necesar să-l salvați din nou în memoria secundară. Dacă nu a fost modificat și există deja o copie în memoria secundară, nu este necesară nicio operație I / O.

Cel mai recent folosit (LRU)

Cea mai bună soluție posibilă ar fi mutarea paginilor care nu vor fi utilizate pentru cel mai mult timp, dar, desigur, sistemul de operare nu este capabil să aibă aceste informații. Soluția de compromis constă în mutarea paginilor care nu au fost folosite pentru cel mai mult timp (LRU, adică cel mai recent folosit ), deoarece au șanse mari să nu fie utilizate din nou imediat. Un marker de timp (Tn) este asociat cu fiecare pagină, care identifică momentul ultimei sale utilizări.

Pentru a gestiona eficient acest algoritm, este necesar suport hardware, deoarece actualizările continue ale marcajului de timp determină o amestecare continuă a paginilor și imposibilitatea determinării paginii care trebuie înlocuită. Puteți implementa această tehnică în două moduri:

  • puteți adăuga la CPU un contor incrementat cu fiecare referință la memorie, un câmp este asociat fiecărui element al tabelului de pagini pentru a păstra marcajul de timp și de fiecare dată când o pagină este accesată, marcatorul său este actualizat utilizând valoarea contorului.
  • păstrați o stivă cu cele mai recente pagini utilizate în partea de sus, pagina din partea de jos a stivei este întotdeauna cea mai recent utilizată.

Ambele metode au un impact considerabil asupra performanței sistemului și din acest motiv sunt fabricate în mod normal în hardware.

Înlocuire pe cont

Sunt algoritmi bazați pe numărarea numărului de referințe făcute la fiecare pagină.

  • LFU (cel mai puțin utilizat): înlocuiește pagina cu cele mai puține referințe. Se bazează pe ideea că o pagină foarte utilizată are un număr mare, în timp ce o pagină care este de puțin folos va avea un număr mic.
  • MFU (cel mai frecvent utilizat): înlocuiește pagina cu cele mai multe referințe. Se bazează pe principiul că o pagină cu număr redus a fost probabil încărcată recent, deci ajută la păstrarea acesteia.

Notă

  1. ^ Memorie virtuală - Paginare ( PDF ), pe users.soe.ucsc.edu .

Bibliografie

Elemente conexe

linkuri externe

Controlul autorității GND ( DE ) 4381328-8
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT