Systemy operacyjne
Transkrypt
Systemy operacyjne
Systemy operacyjne Studia podyplomowe 2015-2016 Wydział Informatyki PB dr inż. Marcin Czajkowski materiały przygotowane przez dr inż. Wojciecha Kwedlo Zarządzanie pamięcią Świat idealny a świat rzeczywisty ● ● ● W idealnym świecie pamięć powinna ... – Mieć bardzo dużą pojemność. – Mieć bardzo krótki czas dostępu – Być nieulotna (zawartość nie jest tracona po wyłączeniu zasilania). W świecie rzeczywistym pamięć jest ... – Szybka – O dużej pojemności – Tania – Wybierz dowolne dwa z trzech powyższych warunków Cel zarządzania pamięcią: – Aby rzeczywistość jak najbardziej przybliżała ideał. Hierarchia pamięci ● Przemieszczając się w dół hierarchii – Zwiększamy czas dostępu – Zmniejszamy koszt jednego bajtu Hierarchia pamięci ● ● ● ● Rejestry procesora: dostęp najszybszy, pojemność najmniejsza. Pamięć podręczna (ang. cache memory). Na ogół kilka poziomów (L1,L2, L3). Przechowuje najczęściej używane dane z pamięci operacyjnej. Często niewidoczna dla programisty aplikacji. – Przykład: AMD Athlon XP. – 128 KB L1 cache (64 KB dane + 64 KB program) – 512 KB L2 cache (dane + program). – L1 znacznie szybsza od L2 Pamięć operacyjna (DRAM). Średnia szybkość i średni koszt. Pamięć dyskowa: Tania, Nieulotna, Duża pojemność, Bardzo duży czas dostępu. Proste zarządzanie pamięcią w systemie jednoprogramowym ● System operacyjny + sterowniki urządzeń ● Jeden program użytkownika => Ochrona pamięci nie jest potrzebna. 0xFFFF 0xFFFF User program (RAM) 0 Operating system (RAM) Operating system (ROM) User program (RAM) Device drivers (ROM) User program (RAM) Operating system (RAM) 0 Systemy wieloprogramowe Partycje o nie zmieniającym się rozmiarze ● ● Pamięć operacyjna podzielona na obszary o stałym rozmiarze. – Rozmiary poszczególnych obszarów mogą się różnić – Do którego obszaru załadować program ? Program ładowany jest do wolnego obszaru. – Wspólna kolejka programów – Odrębne kolejki dla każdego obszaru ● Proces trafia do kolejki związanej z najmniejszym obszarem zdolnym zmieścić proces. 900K Partition 4 Partition 3 Partition 2 900K Partition 4 700K 600K 500K Partition 1 Partition 3 Partition 2 700K 600K 500K Partition 1 100K OS 100K OS 0 0 Dygresja: Określanie adresów danych i instrukcji ● ● W chwili kompilacji. Problem: Nie znamy adresu pod który program zostanie załadowany. W chwili ładowania programu. Generuj kod relokowalny, który może zostać załadowany pod dowolny adres w pamięci. Często wykorzystuje się tablicę relokacji. Kod raz załadowany do pamięci nie może być przemieszczany. – ● W rozwiązaniu z tablicą relokacji używa się adresów bezwzględnych, obliczonych np. względem początku kodu programu. Po załadowaniu do wszystkich adresów bezwzględnych (informacje o adresach bezwzględnych przechowuje tablica relokacji) w kodzie dodaje się adres pod który został załadowany kod programu. W chwili wykonywania programu: Kod załadowany do pamięci może być przemieszczany. – Potrzebne jest wsparcie sprzętowe – Np. rejestr bazowy (i opcjonalnie rejestr limitu) Rejestr bazowy i rejestr limitu ● ● Logiczna i fizyczna przestrzeń adresowa Adres logiczny (zwany czasami adresem wirtualnym): z punktu widzenia procesu ● Adres fizyczny: z punktu widzenia pamięci ● Translacja adresu: AdrFizyczny=RejestrBazowy+AdrLogiczny ● Rejestr Limitu służy do realizacji ochrony pamięci. musi być mniejsze niż L – AdresFizyczny<L Fragmentacja ● ● Fragmentacja wewnętrzna. – Obszar pamięci przydzielony dla procesu jest większy niż niezbędny. – Poważny problem przy partycjach o stałych rozmiarach. Fragmentacja zewnętrzna. – Całkowita pojemność wolnej pamięci jest wystarczająca na zaspokojenie żądania procesu, ale wolna pamięć nie stanowi ciągłego bloku Dynamiczne partycjonowanie ● Rozmiar partycji jest dokładnie równy rozmiarowi procesu – ● ● Brak fragmentacji wewnętrznej. Po pewnym czasie wystąpi fragmentacja zewnętrzna (“dziury w pamięci”) Kompakcja: procesy są przesuwane w pamięci tak, aby wolna pamięć tworzyła jeden duży blok. – Likwiduje fragmentację – Czasochłonna – Problemy z wejściem wyjściem. – Wymaga określania adresów w chwili wykonywania programu, np. Przy pomocy rejestru bazowego Przykład partycjonowania dynamicznego ● Coraz większa fragmentacja zewnętrzna W którym wolnym bloku pamięci umieścić program ? ● First-fit – w pierwszym bloku o wystarczającym rozmiarze ● Best-fit – w najmniejszym bloku o wystarczającym rozmiarze ● Next-fit – następny obszar pasujący po ostatnio wybranym ● Worst-fit- w największym bloku o wystarczającym rozmiarze Wzrost wymagań procesu na pamięć ● ● ● Proces może zwiększać wymagania na pamięć. swoje Dotyczy to stosu i danych. Przydziel większy blok pamięci niż wymagany na początku. – Mała wydajność – Wrócimy do stronicowania.. tego przy Stack Process B Room for B to grow Data Code Stack opisie Process A Room for A to grow Data Code OS Wymiana (ang. swapping) ● Proces może być tymczasowo przeniesiony z pamięci operacyjnej do pamięci pomocniczej (ang. backing store). ● Zwolniona pamięć może zostać wykorzystana przez inne procesy ● Wymianie podlegają kompletne procesy Stronicowanie ● ● ● ● Pamięć fizyczna jest podzielona na ramki (ang. frame) o stałym rozmiarze, będącym potęgą dwójki (np. 4KB). Przestrzeń adresowa procesu jest podzielona na strony (ang. page), rozmiar strony jest równy rozmiarowi ramki. I – tej stronie w przestrzeni adresowej procesu odpowiada K-ta ramka. Dla dowolnego I, K może być dowolne. Adres generowany przez procesor jest podzielony na dwie części: – Numer strony (p) oraz przesunięcie na stronie (d) – Przykład strona ma rozmiar 4KB=2^12 bajtów, adres ma 32 bity 32-12 = 20 bitów p 12 bitów d 32-bitowy adres logiczny Translacja adresu w stronicowaniu Numer strony Przesunięcie CPU p d f Numer ramki 0 1 d .. . 0 1 p-1 p p+1 Numer ramki f-1 f f+1 f+2 .. . f .. . Pamięć Przykład Stronicowanie wymaga wsparcia sprzętowego ● Każdy proces ma własną tablicę stron. ● Tablica stron jest przechowywana w pamięci. ● ● ● ● Adres fizyczny początku tablicy stron jest przechowywany w bazowym tablicy stron. rejestrze Liczba elementów w tablicy stron jest przechowywana w rejestrze długości tablicy stron Zawartość obydwu rejestrów jest zmieniana przy przełączaniu kontekstu. Przy naiwnej sprzętowej implementacji tego schematu każde, odwołanie do pamięci przez proces wymaga wykonania dwóch cykli dostępu do pamięci. – Jeden cykl aby znaleźć numer ramki w tablicy stron. – Jeden cykl na wykonanie właściwej operacji. – Szybkość dostępu do pamięci spada dwukrotnie Bufor TLB (ang. Translation lookaside bufer) ● ● ● ● Przechowywany w procesorze. Zawiera numer strony oraz odpowiadający mu numer ramki dla k (np k=32) najczęściej używanych stron. Jeżeli numer strony występuje w buforze TLB, to nie jest wymagany dostęp do tablicy stron. Jeżeli nie występuje, wykonywany jest dostęp do tablicy stron a para <Strona,Ramka> jest wprowadzana do bufora TLB – ● ● Na którą pozycję ? W praktyce zapewniany jest ponad 95% współczynnik trafień. Uwaga: przełączenie kontekstu opróżnienia bufora TLB !!! wymaga Numer strony 8 unused 2 3 12 29 22 7 Numer ramki 3 1 0 12 6 11 4 Przykładowy bufor TLB Stronicowanie w systemie wieloprogramowym ● ● ● (d) W pamięci procesy A,B,C. (e) Proces B przesłany do obszaru wymiany (f) załadowany proces D Struktury systemu w chwili (f) Realizacja ochrony przy stronicowaniu ● ● ● ● ● Sprzętowy mechanizm ochrony, którego naruszenie (np. przez proces wykonywujący się w trybie użytkownika) powoduje zgłoszenie wyjątku (przerwania) stronicowania (ang. page fault) Możliwość określenia długości tablicy stron (rozmiaru przestrzeni adresów logicznych procesu). Bit ważności związany z każdą stroną i przechowywany w tablicy stron – Strona ważna => obecna w pamięci – Strona nieważna => próba dostępu powoduje wyjątek stronicowania. – Możliwość realizacji “dziur” w logicznej przestrzeni adresowej ● Strony, którym nie odpowiada zaalokowana pamięć mają wyzerowany bit ważności. ● Patrz rysunek w jednym z poprzednich slajdów Bit ochrony przed zapisem – próba zmodyfikowania strony z ustawionym powoduje wyjątek stronicowania. bitem Bit trybu jądra – próba dostępu do strony z ustawionym bitem trybu jądra z procesu wykonywującego się w trybie użytkownika powoduje wyjątek stronicowania => w ten sposób jądro chroni swoją pamięć przed programami użytkowników. Pamięć współdzielona ● pamięć operacyjna ● ● ● Niech pamięć edytora tekstu składa się z 3 stron kodu i jednej strony z danymi. Trzech użytkowników uruchomiło edytor. Czy musimy trzykrotnie wczytać kod do pamięci (razem dziewięć stron) ? Jeżeli kod jest kodem niemodyfikującym się, to nie. – trzy ramki z kodem zostały odwzorowane w przestrzeń adresową trzech procesów, każda z nich jest współdzielona przez trzy procesy. – Wymagana jest implementacja bitu ochrony przed zapisem – aby nie pozwolić żadnemu z trzech procesów na modyfikację stron z kodem. Ponadto pamięć współdzielona może być wykorzystana do bardzo szybkiej wymiany danych pomiędzy procesami – większość systemów posiada niezbędne API. Stronicowanie dwupoziomowe ● ● ● ● ● ● Tablica stron może mieć duży rozmiar. – Niech adres logiczny ma 32 bity, Przestrzeń adresowa na rozmiar 4GB. – Jeżeli pozycja w tablicy stron ma 4 bajty, to na tablicę stron potrzebujemy 4MB. Stronicowanie wielopoziomowe Idea: “Tablica stron podlega stronicowaniu” 220 657 .. . 401 .. . Tablica stron drugiego przechowuje numery stron poziomu 613 .. . 961 Tablica stron pierwszego poziomu przechowuje numery stron w tablicy drugiego poziomu. Każdej pozycji w tablicy stron pierwszego poziomu odpowiada tablica stron drugiego poziomu. 125 884 960 2nd level page tables .. . 955 .. . .. . .. . .. . .. . .. . .. . .. . .. . main memory Przykład Numer strony p1 = 10 bits Page table base Przesunięcie p2 = 9 bits offset = 13 bits Numer ramki 0 1 Adres fizyczny 0 19 1 p1 .. . .. . 0 1 .. . p2 Tablica pier. poziomu 13 .. . .. . Tablica stron drug. poziomu .. . Pamięć Zalety stronicowania ● Eliminuje fragmentacje zewnętrzną ● Fragmentacja wewnętrzna jest ograniczona do rozmiaru strony. ● Łatwa realizacja ochrony pamięci ● Łatwa realizacja dynamicznego wzrostu obszaru przydzielonej pamięci. – ● Wraz z przydzielaniem dodatkowych ramek zaznaczaj bit ważności. Możliwość implementacji pamięci wirtualnej. – Cześć przestrzeni adresowej procesu w pamięci, część na dysku – Rozmiar przestrzeni adresowej procesu większy od pojemności pamięci RAM Pamięć wirtualna Wprowadzenie ● ● ● ● ● ● Podstawowa idea: System operacyjny pozwala na wykorzystanie pamięci o pojemności większej, od zainstalowanej pamięci RAM. Obszary logicznej przestrzeni adresowej, do których proces często się odwołuje przechowywane są w pamięci RAM. Obszary, do których proces odwołuje się rzadko, na dysku. Na dzisiejszym wykładzie skoncentrujemy się na stronicowaniu na żądanie (ang. on-demand paging). Mechanizm pamięci wirtualnej powinien być ukryty przed procesami użytkownika. – Proces “widzi” logiczną przestrzeń adresową od 0 do max_address – System operacyjny bez współpracy procesu przesyła dane do oraz z dysku. Pamięć wirtualna jest szczególnie przydatna w systemach wieloprogramowych. – Podczas gdy proces A jest zablokowany w oczekiwaniu na sprowadzenie danych z dysku, procesor może zostać przydzielony procesowi B. Przypomnienie: Translacja adresu w stronicowaniu Numer strony Przesunięcie CPU p d Numer ramki f ● 0 1 d .. . 0 1 p-1 p p+1 Numer ramki f-1 f f+1 f+2 .. . f Idea pamięci wirtualnej: Przechowuj część stron w pamięci RAM, a część na dysku .. . Pamięć Format pozycji tablicy stron Ochrona Bit modyfikacji ● ● ● ● ● D R V Bit odwołania Numer ramki Bit ważności V (ang. Valid) 1-strona jest w pamięci 0 – strony nie ma w pamięci. – Jeżeli V==0, to próba odwołania do strony generuje wyjątek błędu strony (ang. Page fault) – Jeżeli V==0, to numer ramki jest nieistotny. System operacyjny może w tym miejscu przechować numer bloku dyskowego, w którym zapisano stronę. Ochrona: Pozwolenie na zapis i odczyt (ewentualnie wykonanie). R (ang. Referenced) automatycznie ustawiany na jeden, jeżeli nastąpi odwołanie do strony. D (ang. Dirty) automatycznie ustawiany na jeden, jeżeli strona zostanie zmodyfikowana. R i D muszą być zerowane przez system !!! Przechowywanie stron na dysku ● System operacyjny musi wiedzieć, gdzie znaleźć stronę. – (a) Ciągły obszar w przestrzeni wymiany odpowiada logicznej przestrzeni adresowej. – (b) Numer ramki w tablicy stron identyfikuje (być może przy pomocy tablicy pomocniczej) numer bloku dyskowego Obsługa błędu strony (V==0) ● ● Błąd strony jest przerwaniem. Sprzęt musi umożliwiać wznowienie przerwanej instrukcji. System operacyjny sprawdza, czy chodzi o błędny adres, błąd ochrony, czy też o stronę której nie ma w pamięci. – ● Błędny adres lub błąd ochrony powoduje przerwanie procesu. Jeżeli strony nie ma w pamięci to należy: – Uśpić proces. – Znaleźć wolną ramkę => O tym więcej za chwilę. – Wczytać stronę z dysku do ramki. – Wywołać planistę procesora. – Po pomyślnym odczycie strony Zmodyfikować pozycję w tablicy stron (numer ramki, V=1,D=0,R=0) – Wznowić proces. Wpływ na wydajność ● Czas dostępu do pamięci RAM: 100 ns. ● Czas sprowadzenia strony z dysku: 10 ms. ● Błąd braku strony zwiększa czas dostępu 100 000 razy ● Wniosek: Powinniśmy zadbać o to, aby błędy braku stron występowały bardzo rzadko. Zastępowanie stron (Co robimy, gdy nie ma wolnej ramki) ● ● ● ● Przyjmijmy że procesowi przydzielono k ramek pamięci oraz że wszystkie ramki są już zajęte. W takiej sytuacji przy błędzie braku strony musimy wybrać jedną ze stron obecnych w pamięci (stronę-ofiarę ) – Jeżeli ta strona została zmodyfikowana (D==1), to należy ją zapisać na dysk. – Ramka odpowiadająca wybranej stronie jest zwalniana. Problem: jak wybrać stronę-ofiarę ? – Zazwyczaj chcemy, aby strony, do których proces się często odwołuje, przebywały na stale w pamięci. – Jak określić “częstość” przy ograniczonych możliwościach sprzętowych ? Wybór strony-ofiary jest wykonywany przez algorytm zastępowania stron (ang. page replacement). Porównanie algorytmów zastępowania stron. ● Kryterium: Minimalizacja liczby błędów stron. ● Dla porównania przyjmijmy, że proces się odwołuje kolejno do stron: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. Algorytm FIFO (ang. First In First Out). ● Zastąp stronę, która została sprowadzona jako pierwsza do pamięci. Sprowadzone strony tworzą kolejkę kolejkę. ● Kolejność odwołań: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. ● Jeżeli procesowi przydzielono trzy ramki: ● ● Jeżeli procesowi przydzielono cztery ramki: 1 1 4 5 2 2 1 3 3 3 2 4 1 1 5 4 2 2 1 5 10 błędów stron 3 3 2 4 4 3 9 błędów stron Anomalia Belady'ego: większa liczba ramek niekoniecznie zmniejsza liczbę błędów stron. Algorytm drugiej szansy ● Jest to modyfikacja algorytmu FIFO. ● W standardowym algorytmie FIFO wybierana jest pierwsza strona z kolejki. ● W algorytmie drugiej szansy sprawdzany jest bit odniesienia R. – Jeżeli R==0 (brak odniesienia) to strona jest wybierana na ofiarę. – Jeżeli (R==1) (odniesienie) to: ● R ustawiany jest na zero ● Strona przesunięta jest na koniec kolejki (“otrzymała drugą szansę”). ● Przechodzimy do kolejnej strony w kolejce. Algorytm zegarowy ● ● ● Inne sformułowanie algorytmu drugiej szansy. Wskazówka zegara wskazuje na stronę wybraną do zastąpienia. W przypadku błędu braku strony: – Jeżeli R==0 to zastąp tę stronę – Jeżeli R==1 to ustaw R==0 i przesuń dalej wskazówkę. H t=30 A t=32 t=0 B t=32 t=4 G t=29 F t=22 R==1 E t=21 D J t=15 t=32 R==0 Algorytm optymalny ● Zastąp stronę, do której nie będziemy się odwoływać przez najdłuższy czas ● Kolejność odwołań: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. 1 4 6 błędów strony 2 3 4 5 ● Algorytm niemożliwy do zaimplementowania w praktyce. ● Stosowany do porównywania innych algorytmów. Algorytm LRU (Least recently used) ● Zastąp tę stronę, która nie była najdłużej używana. Zakładamy, że ta strona nie będzie dalej potrzebna ● Brak anomalii Belady'ego. ● Kolejność odwołań: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. 1 5 2 ● 5 4 3 4 Niezły algorytm, ale nadal trudny do zaimplementowania. – ● 3 Większość systemów ma tylko bity R oraz V. W praktyce stosuje się algorytmy przybliżające zasadę LRU. Symulowanie algorytmu LRU ● ● ● ● ● ● Aproksymacja poprzez algorytm NFU (Not Frequently Used). Co pewien czas, w procedurze obsługi, przerwania zegarowego system przegląda tablicę stron. Dla strony w której R==1 zwiększana jest zawartość licznika i R jest ustawiany na zero. W ten sposób strony, do których występuje wiele odwołań, charakteryzują się dużą wartością licznika. Jako ofiara wybierana jest strona o największej wartości licznika. Problem: Strona była często używana 10 sekund temu, obecnie nie jest już używana (Wysoka wartość licznika pozostaje). Postarzanie (ang. aging) Referenced this tick Page 0 Page 1 Page 2 Page 3 Page 4 Page 5 Tick 0 Tick 1 Tick 2 Tick 3 Tick 4 10000000 00000000 10000000 00000000 10000000 10000000 11000000 10000000 01000000 00000000 01000000 11000000 11100000 01000000 00100000 00000000 10100000 01100000 01110000 00100000 10010000 10000000 11010000 10110000 10111000 00010000 01001000 01000000 01101000 11011000 ● Idea: Wraz z upływem czasu zmniejszaj wartości liczników. ● Licznik zajmuje 8 bitów. ● ● W każdym cyklu przesuń zawartość wszystkich liczników w prawo (podziel przez dwa). Jeżeli było odwołanie to ustaw najstarszy bit na jeden. Zatem algorytm wygląda tak: counter/=2 if (referenced) counter+=128 Pobieranie stron do pamięci ● ● ● Pobieranie w momencie wystąpienia błędu braku strony. Jeżeli strona jest tylko do odczytu, np. kod programu to możemy wczytać ją z pliku wykonywalnego. – Przy starcie procesu żadna strona nie jest w pamięci. – Duża liczba błędów strony przy starcie programu. – Fragmenty kodu, które nie są wykorzystane, nie zostaną wczytanie do pamięci. Wczytuj strony grupami. – Jeżeli mamy odwołanie do strony a, to prawdopodobne są odwołanie do stron a+1,a+2,... Zapisywanie zmodyfikowanych stron ● ● Strona zapisywana w momencie jej zastąpienia. – Mała liczba zapisów na dysk – Algorytm powolny: brak strony powoduje konieczność zapisania strony na dysk i wczytania strony z dysku. Strony zapisywane periodycznie w tle. – Proces drugoplanowy przegląda strony i zapisuje strony zmodyfikowane (D==1), do których ostatnio nie było odwołań. – Zapisanie strony powoduje skasowanie bitu D. – Proces drugoplanowy może zapisywać strony grupami => większa wydajność operacji dyskowych. Stronicowanie na żądanie w systemie wieloprogramowym ● Jak dotąd nie uwzględnialiśmy faktu współistnienia wielu procesów ● Zastępowanie stron w systemie wieloprogramowym. ● – Lokalne: strona-ofiara jest wybrana wyłącznie spośród stron procesu. – Globalne: strona-ofiara jest wybrana spośród stron wszystkich procesów Problem: Jak rozdzielić dostępne ramki pomiędzy procesy – Przydziel stałą liczbę ramek: 100 ramek, 5 procesów, przydziel po 20 ramek. – Przydziel liczbę ramek proporcjonalną do rozmiaru procesu. Dynamiczna alokacja ramek ● Obserwuj częstość błędów stron. – Jeżeli zbyt dużą, to przydziel dodatkowe ramki – Jeżeli zbyt mała, to zabierz ramki Buforowanie stron ● ● ● Zastępowanie stron niekoniecznie musi być przeprowadzane w momencie wystąpienia błędu braku strony. Odzyskane strony są umieszczane na jednej z dwóch list. – Lista stron zmodyfikowanych – Lista stron niezmodyfikowanych – bufor stron (ang. page buffer) Strony z listy stron zmodyfikowanych są grupami zapisywane na dysk i przenoszone do listy stron niezmodyfikowanych stron ● W przypadku zapotrzebowania na nową ramkę przydzielana jest jedna ramka ● Z bufora stron. ● W przypadku wystąpienia błędu braku stron sprawdzamy, najpierw sprawdzamy czy ta strona jest na jednej z dwóch list. Szamotanie (ang. trashing) ● Jeżeli liczba ramek jest zbyt mała liczba błędów braku strony jest bardzo duża. Procesy ciągle oczekują na sprowadzenie stron z dysku i na dysk. – Wykorzystanie procesora jest bardzo małe. System (wsadowy) może zdecydować o uruchomieniu dodatkowych procesów, co dodatkowo zmniejszy liczbę wolnych ramek i zwiększy szamotanie. Pamięć wirtualna, a we-wy ● Proces P1 zgłasza żądanie odczytu z we-wy do bufora w swojej pamięci. – Czy strony, w których znajduje się bufor, są w pamięci ? Jeżeli nie, to strony trzeba sprowadzić z dysku. ● Gdy P1 czeka na wykonanie odczytu, wykonuje się P2 ● P2 zgłasza błąd strony. ● ● Problem: do zastąpienia może być wybrana strona P1, w której znajduje się bufor. Blokowanie (ang. locking) stron. – Strona zablokowana nie może być wybrana do zastąpienia. – Strony powinny pozostawać zablokowane przez stosunkowo krótki czas. Optymalizacja kodu ● ● ● Array A[1024, 1024] of integer, A[wiersz,kolumna] Każdy wiersz (4KB) jest przechowany na jednej stronie Procesowi przydzielono jedną ramkę (4KB) – – Program 1 for j := 1 to 1024 do for i := 1 to 1024 do A[i,j] := 0; 1024 x 1024 błędów strony Program 2 for i := 1 to 1024 do for j := 1 to 1024 do A[i,j] := 0; 1024 błędy strony ● Należy preferować kod odwołujący się do komórek pamięci o kolejnych adresach. (również ze względu na optymalne wykorzystanie pamięci podręcznej i szyny procesora).