This shows you the differences between two versions of the page.
so:cursuri:curs-06 [2014/03/22 21:54] razvan.deaconescu [Investigarea mapării folosind pmap] |
so:cursuri:curs-06 [2019/03/24 14:10] (current) razvan.deaconescu |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Curs 06 - Memoria virtuală ====== | ====== Curs 06 - Memoria virtuală ====== | ||
- | |||
- | <html> | ||
- | <iframe src="http://prezi.com/embed/qshrq7oeytj2/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&features=undefined&disabled_features=undefined" width="550" height="400" frameBorder="0"></iframe> | ||
- | </html> | ||
* [[http://prezi.com/qshrq7oeytj2/?utm_campaign=share&utm_medium=copy&rc=ex0share | Curs 06 - Memoria virtuală (vizualizare Prezi)]] | * [[http://prezi.com/qshrq7oeytj2/?utm_campaign=share&utm_medium=copy&rc=ex0share | Curs 06 - Memoria virtuală (vizualizare Prezi)]] | ||
* [[http://elf.cs.pub.ro/so/res/cursuri/SO_Curs-06.pdf | Curs 06 - Memoria virtuală (PDF)]] | * [[http://elf.cs.pub.ro/so/res/cursuri/SO_Curs-06.pdf | Curs 06 - Memoria virtuală (PDF)]] | ||
+ | |||
+ | * [[https://drive.google.com/open?id=1jsFIY2bG2QssLX1X9AWn4_0Ec2x_hK9oOGohmFqKSRM|Notițe de curs]] | ||
* Suport curs | * Suport curs | ||
* Operating Systems Concepts Essentials | * Operating Systems Concepts Essentials | ||
* Capitolul 8 - Virtual Memory | * Capitolul 8 - Virtual Memory | ||
- | * Modern Operating Systems | + | * Modern Operating Systems, 2nd Ed. |
* Capitolul 4 - Memory Management | * Capitolul 4 - Memory Management | ||
* Secțiunile 4.4, 4.5 | * Secțiunile 4.4, 4.5 | ||
+ | * Modern Operating Systems, 3rd Ed. | ||
+ | * Capitolul 3 - Memory Management | ||
+ | * Secțiunile 3.4, 3.5 | ||
+ | * [[http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/|Anatomy of a Program in Memory]] | ||
+ | |||
+ | <html> | ||
+ | <center> | ||
+ | <iframe src="https://prezi.com/embed/qshrq7oeytj2/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&features=undefined&disabled_features=undefined" width="550" height="400" frameBorder="0"></iframe> | ||
+ | </center> | ||
+ | </html> | ||
===== Demo-uri ===== | ===== Demo-uri ===== | ||
Line 98: | Line 106: | ||
Observăm de asemenea, că se realizează un număr redus de apeluri de sistem ''brk'' raportat la cele ''1024'' de apeluri de bibliotecă ''malloc''. Un apel ''brk'' alocă un pool mai mare de memorie care va fi apoi folosit la apeluri viitoare ''malloc''; realizează o prealocare. | Observăm de asemenea, că se realizează un număr redus de apeluri de sistem ''brk'' raportat la cele ''1024'' de apeluri de bibliotecă ''malloc''. Un apel ''brk'' alocă un pool mai mare de memorie care va fi apoi folosit la apeluri viitoare ''malloc''; realizează o prealocare. | ||
- | Pentru a vedea comportamentului funcției de bibliotecă ''mallooc'', actualizăm codul astfel încât ''malloc'' să aloce, la fel ca ''mmap'' calupuri de ''1MB'' de memorie. Adică bucla ''for'' aferentă să arate așa:<code c> | + | Pentru a vedea comportamentului funcției de bibliotecă ''malloc'', actualizăm codul astfel încât ''malloc'' să aloce, la fel ca ''mmap'' calupuri de ''1MB'' de memorie. Adică bucla ''for'' aferentă să arate așa:<code c> |
for (cnt = 0; cnt < NUM_ROUNDS; cnt++) { | for (cnt = 0; cnt < NUM_ROUNDS; cnt++) { | ||
puts("Using malloc to allocate 1024 sets of 1024 bytes."); | puts("Using malloc to allocate 1024 sets of 1024 bytes."); | ||
Line 113: | Line 121: | ||
</code> | </code> | ||
- | Observăm că acum și funcția de bibliotecă ''malloc'' folosește în spate tot apelul de sistem ''mmap''. Acesta alocă doar memorie virtuală de unde și comportamentul. De la un valoare dată, alocarea cu ''malloc'' folosește apelul de sistem ''mmap''. | + | Observăm că acum și funcția de bibliotecă ''malloc'' folosește în spate tot apelul de sistem ''mmap''. Acesta alocă doar memorie virtuală de unde și comportamentul. De la o valoare dată, alocarea cu ''malloc'' folosește apelul de sistem ''mmap''. |
<spoiler Despre apelul malloc> | <spoiler Despre apelul malloc> | ||
Line 158: | Line 166: | ||
</spoiler> | </spoiler> | ||
- | ==== Page-Faulturi ==== | + | ==== Page fault-uri la fork (copy-on-write) ==== |
- | Vrem să vizualizăm spațiul virtual de adrese al unui proces. Pentru aceasta, accesăm subdirectorul ''pmap''; urmărim conținutul fișierului ''pmap.c''; facem mapări (folosind apelul ''mmap'') folosind diverse flag-uri. | + | Vrem să urmărim realizarea page fault-urilor în urma unui apel ''fork''; page fault-urilor vor fi cauzate de mecanismul de copy-on-write în momentul în care unul dintre cele două procese (copil sau părinte) scrie în zona respectivă. Pentru aceasta, accesăm subdirectorul ''fork-faults''; urmărim conținutul fișierului ''fork-faults.c''. În cadrul fișierului ''fork-faults.c'' se execută următorii pași: |
+ | - se alocă memorie virtuală folosind ''mmap'' | ||
+ | - se alocă memorie fizică pentru paginile de mai sus, folosind //(on) demand paging// prin accesarea primului octet al fiecărei pagini | ||
+ | - se creează un proces nou | ||
+ | - procesul copil citește valoarea din prima jumătate a numărului de pagini (**doar** citește) | ||
+ | - procesul copil scrie o valoare în cadrul fiecărei pagini din a două jumătate | ||
+ | - procesul părinte scrie o valoare în toate paginile | ||
- | * Intrați în directorul ''5-fork-faults/''. | + | Ca să urmărim ce se întâmplă, compilăm fișierul folosind ''make''. Apoi rulăm programul obținut:<code bash> |
- | * Consultați fișierului ''fork-faults.c''. | + | ./fork-faults |
- | * **Câte page-fault-uri** credeți că se realizează la rulare? | + | </code> Folosim ''ENTER'' pentru a continua programul, dar după rularea ''pidstat'' (mai jos). |
- | * Compilați fișierul. | + | |
- | * Rulați programul ''fork-faults''. | + | Într-o altă consolă folosim utilitarul ''pidstat'' din pachetul ''sysstat'' care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului ''-r''). Dacă nu există comanda ''pidstat'' trebuie să instalăm pachetul ''sysstat'' folosind comanda:<code bash> |
- | * Folosiți ''ENTER'' pentru a continua programul, dar după rularea ''pidstat'' (vedeți mai jos). | + | |
- | * Pe un alt terminal sau tab de terminal folosiți utilitarul ''pidstat'' din pachetul ''sysstat'' care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului ''-r''). | + | |
- | * Dacă nu merge comanda ''pidstat'' trebuie să instalați pachetul ''sysstat'' folosind comanda:<code bash> | + | |
apt-get install sysstat | apt-get install sysstat | ||
</code> | </code> | ||
- | * Folosiți comanda <code bash> | + | |
+ | Pentru a rula ''pidstat'' și a urmări page fault-urile, folosim, pe a doua consolă, comanda<code bash> | ||
pidstat -r -T ALL -p $(pidof fork-faults) 5 100 | pidstat -r -T ALL -p $(pidof fork-faults) 5 100 | ||
- | </code> pentru a urmări page fault-urile. | + | </code> Comanda de mai sus afișează câte un mesaj la fiecare 5 secunde. În prima consolă apăsăm ''ENTER'' pentru a continua rularea și urmărim informațiile afișate de ''pidstat'', apoi continuăm apăsarea ''ENTER'' etc. |
- | * Comanda de mai sus vă afișează câte un mesaj la fiecare 5 secunde. Sincronizați apăsarea tastei ''ENTER'' cu afișajul comenzii ''pidstat''. | + | |
- | * Urmăriți evoluția numărului de page fault-uri pentru cele două procese: părinte și copil. | + | Urmărim, în outputul comenzii ''pidstat'', evoluția numărului de page fault-uri pentru cele două procese: părinte și copil. Page fault-urile care apar în cazul unui copy-on-write în procesul copil vor fi vizibile ulterior și în procesul părinte. Observăm că procesul copil generează page fault-uri doar pe jumătate din pagini (cele în care scrie), iar procesul părinte generează page fault-uri pe toate paginile. Asta pentru că un proces creează o copie a paginilor inițiale, dar lasă acele pagini ''read-only'', iar alt proces primește page fault dar doar schimbă permisiunile din read-only în read-write. |
- | * Page fault-urile care apar în cazul unui copy-on-write în procesul copil vor fi vizibile ulterior și în procesul părinte. | + |