# Lista 14 (17 czerwca 2021)
###### tags: `ask21` `ćwiczenia` `kba`
## Deklaracje
Gotowość rozwiązania zadania należy wyrazić poprzez postawienie X w odpowiedniej kolumnie! Jeśli pożądasz zreferować dane zadanie (co najwyżej jedno!) w trakcie dyskusji oznacz je znakiem ==X== na żółtym tle.
**UWAGA: Tabelkę wolno edytować tylko wtedy, gdy jest na zielonym tle!**
:::danger
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8(B)|
| ---------------------:| --- | --- | --- | --- | --- | --- | --- | --- |
| Andriy Bernad | X | X | X | | | X | X | X | 6
| Wojciech Bogucki | | | | | | | | | 0
| Michał Doros | X | X | X | X | X | X | X | X | 8
| Marko Golovko | | | | | | | | | 0
| Magdalena Jarecka | | | | | | | | | 0
| Szymon Jędras | X | X | X | X | | X | X | | 6
| Heorhii Karpenko | X | X | X | | | X | X | X | 6
| Szymon Kosakowski | X | X | X | | | | X | | 4
| Izabella Kozioł | | | | | | | | | 0
| Franciszek Malinka | X | X | X | X | |==X==| X | X | 7
| Filip Pazera | | | | | | | | | 0
| Franciszek Pindel | | | | | | | | | 0
| Kacper Puchalski | | | | | | | | | 0
| Kacper Solecki | X | X | X | X | X | X | X | X | 8
| Andrzej Tkaczyk | | | | | | | | | 0
| Łukasz Wasilewski | | | | | | | | | 0
| Vladyslav Yablonskyi | X | X | X | | | X | X | | 5
| Adam Zyzik | | | | | | | | | 0
:::
## Zadanie 1
:::success
Autor: Grzegorz Karpenko
:::
**Przestrzeń adresowa** – zbiór możliwej do zaadresowania przez proces pamięci. Nie cały jej obszar musi mieć swój odpowiednik w pamięci fizycznej, co jest implementowane za pomocą pamięci wirtualnej.
Pamięć wirtualna działa na zasadzie przedefiniowania adresów pamięci (fizycznych) na adresy używane przez procesy (**adresy wirtualne**) tak, aby "oszukać" procesy i dać im wrażenie pracy w ciągłej przestrzeni adresowej. **Pamięć wirtualna** oznacza znacznie większą ilość pamięci RAM dla procesu niż fizycznie dostępna w systemie.
**Stronicowanie** – jeden ze sposobów rozwiązania problemu zewnętrznej fragmentacji, polegający na dopuszczeniu nieciągłości rozmieszczenia logicznej przestrzeni adresowej procesu w pamięci fizycznej. Pamięć fizyczna dzielona jest na bloki stałej długości zwane ramkami. Pamięć logiczna dzielona jest na bloki stałej długości zwane **stronami**. Rozmiary stron i ramek są identyczne.
**Tablica stron** służy do odwzorowania stron wirtualnych na strony fizyczne. Z matematycznego punktu widzenia tabela stron jest funkcją, w której numer wirtualnej strony stanowi argument, a numer strony fizycznej - wynik. Dzięki wykorzystaniu wyniku tej funkcji można zastąpić pole numeru strony w adresie wirtualnym polem ramki strony i w ten sposób utworzyć adres w pamięci fizycznej.
**Wpis tablicy stron** - to rekord tablicy stron, VPN, PPN(część adresu fizycznego) oraz bit valid.
:::spoiler Rysunek

:::
**Stronicowanie dwupoziomowe** - metoda oszczędzania pamięci, gdzie tablica stron sama podzielona jest na strony.
32-bitowe adresy wirtualne
page size: 4 KB = 4096 bajt = $2^{12}$
wpis tablicy stron zajmuje: 4 bajty = $2^2$
rozmiar przestrzeni adresowej 1GB = $2^{30}$ bajt
rozmiar tablicy stron:
(a) **jednopoziomowej**
$2^{32}/2^{12}$(rozmiar_adresu / rozmiar_strony) = $2^{20} stron = 1048576 = 1 MB$
Każdy wpis zajmuje 4 bajty więc rozmiar tablicy stron jest równy $2^{20}*4=4MB$
(b) **dwupoziomowej**, gdzie katalog tablicy stron ma 1024 wpisy
**MAX**
Każda strona drugiego poziomu może mapować maksymalnie $2^{10}*2^{12}=2^{22}$ bajt (liczba_wpisów * page_size)
$2^{32}/2^{22}=2^{10}=1024$ liczba stron drugiego poziomu.
1024+1(jedna strona 1 poziomu) = $1025*4 = 4MB + 4KB$
**MIN**
Ponieważ potrzebujemy tylko 1GB przestrzeni, pozostałe 3GB nie musimy mapować i możemy zostawić ich jako puste wpisy w tablice 1 poziomu:
$2^{30}/2^{22}=2^{8}=256$ liczba stron drugiego poziomu.
256+1(jedna stron 1 poziomu) = $257*4 = 1MB + 4KB$
## Zadanie 2
:::success
Autor: Andrzej Bernad
:::
:::info
Zakładamy taki sam model podsystemu pamięci jak na slajdach do wykładu „Virtual Memory:Systems” (strony 9–16). Powtórz proces translacji adresów i adresowania pamięci podręcznej dla adresów:0x027c, 0x03a9 i 0x0040 zakładając poniższy stan TLB, pamięci podręcznej i tablicy stron.
:::

Bufor **TLB** (ang. translation lookaside buffer) (czasami pamięć asocjacyjna) to rodzaj pamimięci podręcznej służący do odwzorowywania adresów wirtualnych na fizyczne bez konieczności sięgania do tabeli stron. Zwykle jest ono zlokalizowane wewnątrz jednostki MMU i składa się z niewielkiej liczby pozycji - każda pozycja zawiera informacje dotyczące jednej strony, obejmują one numer strony wirtualnej (VPN), bit ustawiany w przypadku gdy strona jest zmodyfikowana, kod zabezpieczenia (uprawnienia czytania/pisania/uruchamiania) oraz fizyczną ramkę strony wskazującą na lokalizację strony w pamięci fizycznej. Pola te odpowiadają jeden do jednego polom w tabeli stron, wyjątkiem jest numer strony wirtualnej, który nie jest potrzebny w tabeli stron. Kolejny bit wskazuje na to, czy pozycja jest ważna (tzn. czy jest w użyciu), czy nie.
Działamy na adresach wirtualnych i fizycznych. Adres wirtualny ma 8 bitów VPN, z czego $a_{13},\dots, a_{8}$ to TLBT (bity tagu bufora), $a_7, a_6$ to TLBI (bity indeksu zbioru bufora). Przesunięcie wirtualnej strony (VPO) jest równe przesunięciu fizycznej strony (PPO), a więc bity te kopiujemy za każdym razem. W adresie fizycznym bity $a_{11},\dots,a_6$ to bity znacznika pamięci podręcznej, $a_5,\dots, a_2$ to bity indeksu zbioru, a $a_1, a_0$ to bity przesunięcia.

32 bit addresses, 4KB pages, 4-byte PTEs
1) 0x027c = 000010|01|111100 - virtual address
TLBI:0x1 TLBT:0x02 PPN:17 V:1
Z tablicy stron PPN:17 -> VPN:09
| TLBI | TLBT | PPN | V | TLB | VPN |
|:----:|:----:|:----:|:---:|:---:|:----:|
| 0x1 | 0x02 | 0x17 | 1 | hit | 0x09 |
010001|1111|00 - physical address
2 nisze bity to CO(cache offset)
następne 4 bity CI(cache index)
wysze 6 bitów CT(cache tag)
| CO | CI | CT |
|:---:|:----:|:----:|
| 0x0 | 0x0F | 0x09 |
W pamięci podręcznej szukamy index F. Sprawdzamy czy tag równy 0x09, bierzemy wartość pod offsetem 0. Wartość: DE
2) 0x03a9 = 000011|10|101001
| TLBI | TLBT | V | TLB |
|:----:|:----:|:---:|:----:|
| 0x2 | 0x03 | 0 | miss |
Sprawdzamy czy jest wpis w tablice stron.
VPN = 00001110 = 0x0E -> PPN:11
Dadajemy do TLB wpis tag:0x03 PPN:11 V:1
| TLBI | TLBT | PPN | V |
|:----:|:----:|:----:|:---:|
| 0x2 | 0x03 | 0x11 | 1 |
10001|1010|01 - physical address
| CO | CI | CT | cache |
|:---:|:----:|:----:|:-----:|
| 0x1 | 0x0A | 0x11 | miss |
3) 0x0040 = 000000|01|000000
TLBI:0x1 TLBT:0x00 TLB:miss
VPN = 00000001 = 0x01
| TLBI | TLBT | VPN | TLB |
|:----:|:----:|:----:|:----:|
| 0x2 | 0x03 | 0x01 | miss |
W tablice stron dla VPN=0x01 bit valid jest ustawiony na 0 więc mamy Page Fault
## Zadanie 3
:::success
Autor: Franciszek Malinka
:::
**TLB w pełni asocjacyjne** - pamięć podręczna, w której wszystkie linie są w jednym zbiore (tzn. nie ma indeksu, są tylko tagi).
**ofiara** - kiedy następuje chybienie w pamięć podręczną następuje wymiana strony i trzeba wybrać stronę w pamięci, która zostanie usunięta.
**błąd strony** - wyjątek rzucany przez hardware kiedy proces odwołuje się do pamięci wirtualnej, która nie mapuje pamięci załadowanej do RAMu.
**wtoczyć (swap-in)** - w momencie page faulta spowodowanego tym, że strona jest na dysku, należy ją wczytać (czyli wtoczyć) do pamięci RAM.
Ze względu na to, że strony mają 4KiB, to tylko najstarsze 4 bity adresu wirtualnego stanowią tag w TLB.
- Adres 0x123d - tag 0x1. TLB miss, zaglądamy do tablicy stron i mamy page fault, strona na dysku. Pojawia się wpis |01|1|0D|. TLB:
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 0b | 1 | 0c |
| 1 | 07 | 2 | 04 |
| 1 | 03 | 3 | 06 |
| 1 | 01 | 0 | 0d |
- Adres 0x08b3, tag 0x0, TLB miss, PT hit, PPN = 5
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 0b | 2 | 0c |
| 1 | 07 | 3 | 04 |
| 1 | 00 | 0 | 05 |
| 1 | 01 | 1 | 0d |
- Adres 0x365c, tag 0x3, TLB miss, PT hit, PPN = 6
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 0b | 3 | 0c |
| 1 | 03 | 0 | 06 |
| 1 | 00 | 1 | 05 |
| 1 | 01 | 2 | 0d |
- Adres 0x871b, tag 0x8, TLB miss, Page fault, strona na dysku, zmiana w tablicy stron: |08|1|0e|.
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 08 | 0 | 0e |
| 1 | 03 | 1 | 06 |
| 1 | 00 | 2 | 05 |
| 1 | 01 | 3 | 0d |
- Adres 0xbee6, tag 0xb, TLB miss, PT hit, PPN = 0c
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 08 | 1 | 0e |
| 1 | 03 | 2 | 06 |
| 1 | 00 | 3 | 05 |
| 1 | 0b | 0 | 0c |
- Adres 0x3140, tag 0x3, TLB hit, PT hit, PPN = 6.
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 08 | 2 | 0e |
| 1 | 03 | 0 | 06 |
| 1 | 00 | 3 | 05 |
| 1 | 0b | 1 | 0c |
- Adres 0xc049, tag 0xc, TLB miss, page fault, adres wskazuje na null.
Ostateczne TLB:
Tlb:
| Valid | Tag | LRU | PPN |
| ----- | --- | --- | --- |
| 1 | 08 | 2 | 0e |
| 1 | 03 | 0 | 06 |
| 1 | 00 | 3 | 05 |
| 1 | 0b | 1 | 0c |
Ostateczna tablica stron:
| VPN | Valid | PPN |
|:--- | ----- | --- |
| 00 | 1 | 05 |
| 01 | 1 | 0d |
| 02 | 0 |dysk |
| 03 | 1 | 06 |
| 04 | 1 | 09 |
| 05 | 1 | 0B |
| 06 | 0 | dysk|
| 07 | 1 | 04 |
| 08 | 1 | 0e |
| 09 | 0 | dysk|
| 0a | 1 | 03 |
| 0b | 1 | 0C |
| 0c | 0 | brak|
## Zadanie 4
:::danger
Autor: Szymon Jędras
:::

**deskryptory stron** - wpisy tablicy stron
**deskryptory katalogów stron** - wpisy tablicy katalogów stron
**algorytmy zastępowania stron** - algorytm decydujący którą strone najlepiej zastąpić.
##### Deskryptory Katalogów stron

**XD** - (ang. execute disable) mówi czy dana strona zawiera instrukcje, czy pamięć jest wykonywalna
**base addr** - 40 najbardziej znaczących bitów adresu fizycznego następnego poziomu tłumaczenia.
**G** - (ang. Global) strona globalna (powoduje że strona nie jest wyrzucana z TLB przy zmianie zadania - task).
**PS** - (ang. Page Size) mówi o rozmiarze strony 4KB lub 4MB (zdefiniowana na pierwszym poziomie).
**A** - (ang. Reference bit) czy strona była odczytywana lub modyfikowana w trakcie ostatniego okresu czasu (okres definiowany prez OS).
**CD** - (ang. Caching disabled) oznaczenie tego bitu spowoduje że strona nie będzie zapisywana w cache (przydatne np jeśli strona wskazuje na dane dotyczące zegara).
**WT** - (ang. Write-through) mówi czy wybrana została polityka Write-through czy Write-back.
**U/S** - (ang. User-supervisor mode) mówi czy strona jest dostępna dla użytkownika w normalnym trybie, czy tylko dla trybu uprzywilejowanego.
**R/W** - (ang. read/write) mówi czy dane są tylko do odczytu, czy można je modyfikować.
**P** - mówi czy istnieją w pamięci fizycznej czy nie (swego rodzaju bit valid).

**base addr** - 40 najbardziej znaczących bitów adresu fizycznego tłumaczonego adresu
**D** - (ang. Dirty bit) czy strona była modyfikowana w trakcie ostatniego okresu czasu (okres definiowany prez OS).
Pozostałe jak powyżej.
##### Czemu jądro systemu operacyjnego zmienia niektórym stronom domyślną politykę zarządzania pamięcią podręczną dla zawartości strony przy pomocy bitów CD i WT [3, §4.9]?
Używamy **CD**, gdy zależy nam żeby dane były świeże np, zegar albo I/O.
Używamy **WT**, gdy zależy nam, żeby dane były jak najszybciej dostępne innym procesom, np I/O, wtedy chcemy, żeby była używana polityka write-back, w przeciwnych wypadkach chcemy używać write-through jako, że jest to szybsze.
##### W jakim celu algorytmy zastępowania stron pamięci wirtualnej korzystają z bitów A i D [3, §4.8]?
Procesor wykorzystuje bit **A** do oznaczenia że do tej strony się odwołano.
Procesor wykorzystuje bit **D** do oznaczenia, że ta strona została modyfikowana.
Te flagi są używane przez software do zarządzania transferem stron.
##### Jak jądro konfiguruje odpowiednie części wirtualnej przestrzeni adresowej przy pomocy bitów R/W, XD i U/S [3, §4.6]?
Dokumentacja opisuje bardzo zaawansowane relacje pomiędzy tymi bitami oraz rejestrami kontrolnymi. Między innymi:
Jeśli mamy dostęp zwykłego trybu działanie jest takie jakby się można spodziewać, tj:
- Jeśli U/S = 1, nie można ruszyć tej pamięci (zostanie rzucony wyjątek).
- Jeśli R/W = 1 w każdej strukturze, można modyfikować tą pamięć.
- Jeśli XD = 1 w chociaż jednej strukturze, nie można wczytywać instrukcji do wykonania jeśli IA32_EFER.NXE = 1.
W wypadku uprawnień trybu uprzywilejowanego sprawy się trochę komplikują, ale z grubsza działa to tak:
- Czy proces może czytać dane zależy od CR4.SMAP i EFLAGS.AC
- Czy proces może modyfikować dane zależy głównie od CR4.SMAP, EFLAGS.AC i CR0.WP.
- Czy proces może wykonywać dane zależy od CR4.MEP i IA32_EFER.NXE
> Tryb uprzywilejowany w tym kontekście oznacza dostęp gdzie current privilege level, CPL < 3 oznacza tryb uprzywilejowany, a CPL = 3 oznacza tryp zwykły.
> IA32_EFER.NXE - konfiguruje czy procesor ma zwracać uwagę na bit XD, podczas wczytywania instrukcji.
> EFLAGS.AC - alignment check, ustawienie tej flagi powoduje chwilowe wyłączenie CR4.SMAP w celu wykonania jawnego dostępu do pamięci uprzywilejowanej, przy uprawniniom użytkownika
## Zadanie 5
:::success
Autor: Michał Doros
:::
**zbiór roboczy** - pamięć, której proces używa w danym przedziale czasowym (lub ostatnie $k$ stron do których były odwołania)
4-drożne TLB, 64 wpisy
- wariant optymistyczny: proces robi dostępy do dokładnie 4 stron z każdego zbioru w TLB.
Zbiór roboczy ma wtedy $64$ strony $= 2^{18}$ bajtów (przy założeniu rozmiaru strony $4$KiB)
- wariant pesymistyczny: proces robi dostępy do stron tylko z jednego zbioru.
Zbiór roboczy ma wtedy $4$ strony $= 2^{14}$ bajtów.
**duże strony** - strony o rozmiarze większym niż standardowy (4KiB) pozwalające na częstsze trafienia w TLB. Pamięć przypisana (przypisywana w czasie startu systemu) dużym stronom zawsze znajduje się w pamięci pierwszego rzędu i nigdy nie jest swapowana.

> https://docs.oracle.com/database/121/UNXAR/appi_vlm.htm#UNXAR401
Jeżeli dopuścimy duże strony rozmiaru $4$MiB szacowania zwiększą się $1024$ razy.
Na używaniu dużych stron mogą skorzystać programy o dużym, uporządkowanym zbiorze roboczym, np. bazy danych.
W tablicy stron duże strony można zakodować bitem **PS** - wtedy wpis katalogu nie wskazuje do kolejnej tablicy, ale bezpośrednio na dużą stronę.
## Zadanie 6
:::danger
Autor: Władysław Jabłoński
:::
:::spoiler Schemat

:::
Gdy procesor generuje adres fizyczny, najpierw jest robiony dostęp do pamięci podręcznej, a już później do pamięci głównej. Dane są sprawdzane w pamięci podręcznej za pomocą znacznika i indeksu / zestawu bitów, jak pokazano tutaj.
Taka pamięć podręczna, w której bity tagu i indeksu są generowane wprost z adresu fizycznego, nazywana jest pamięcią podręczną **fizycznie indeksowaną** i **znakowaną fizycznie**.
:::spoiler Schemat

:::
Pamięć **indeksowana wirtualnie** i **znakowana fizycznie** używa bitów tagu z adresu fizycznego i indeksu jako indeksu z adresu wirtualnego.
Pamięć podręczna jest przeszukiwana przy użyciu adresu wirtualnego i uzyskuje się część znacznika adresu fizycznego.
TLB jest przeszukiwany za pomocą adresu wirtualnego i uzyskiwany jest adres fizyczny. Na koniec część tagu adresu fizycznego uzyskana z pamięci podręcznej jest porównywana z tagiem adresu fizycznego uzyskanym z TLB. Jeśli oba są takie same, jest to trafienie w pamięci podręcznej, w przeciwnym razie chybienie.
Jak widać na rysunku dostęp do pamięci podręcznej, jak i dostęp do TLB jest robiony jednocześnie. Ma to sens, bo TLB z reguły jest mniejsze i dostęp do niego jest znacznie szybszy niż do pamięci podręcznej. Więc pomijanie TLB (jak to jest robione w wirtualnie indeksowanej, wirtualnie znakowanej pamięci podręcznej) tutaj by nic nie przyspieszyło, a niektóre flagi z TLB czasami koniecznie potrzebujemy.
Także nie potrzebujemy wyczyszczać cache przy zmianie procesu. Ponieważ wykorzystywana jest część adresu fizycznego jako indeks, każdy dostęp do pamięci w systemie będzie odpowiadał unikatowy adres fizyczny i dane dla wielu procesów mogą znajdować się w pamięci podręcznej, a zatem nie ma potrzeby opróżniania danych dla każdego przełączania kontekstu.
Zalety wirtualnie indeksowanej fizycznie oznaczonej pamięci podręcznej:
1. Szybki dla małego kontekstu danych, gdzie dostęp do pamięci podręcznej jest częsty
2. Unika wyczyszczania pamięci podręcznej przy przełączaniu kontekstu
3. Dostęp do flag TLB można uzyskać równolegle z dostępem do pamięci podręcznej
## Zadanie 7
:::danger
Autor: Szymon Kosakowski
:::
W systemie potrzeba zmiany przestrzeni adresowej zachodzi kiedy zmieniany jest obecnie wykonywany proces - każdy proces ma swoją wirtualną przestrzeń adresową.
Przestrzeń adresowa w trybie jądra jest taka sama dla wszystkich procesów. Wymiana danych między przestrzeniami wirtualnymi w trybie jądra i w trybie użytkownika wymaga pewnych dodatkowych zabiegów, np. zapis z przestrzeni jądra pod wskazany adres wirtualny w przestrzeni adresowej użytkownika wiąże się ze sprawdzeniem, czy adres ten jest prawidłowy.
przełączanie przestrzeni adresowej - zmiana zawartości wirtualnej przestrzeni adresowej i tablicy stron.
Podczas zmiany przestrzeni adresowej należałoby wyczyścić TLB, ponieważ różne procesy mają rozłączne wirtualne przestrzenie adresowe i mogą mieć przypisany inny adres fizyczny dla tego samego adresu wirtualnego. Chcemy uniknąć sytuacji, w której obecny proces skorzysta z mapowania adresu dla poprzedniego procesu. Czyszczenie TLB można wykonać ustawiająć wszystkie bity *valid* we wpisach w TLB na $0$. Wtedy po zmianie procesu żaden odczyt z TLB nie będzie trafiony.
Chcemy uniknąć czyszczenia TLB, ponieważ po wczytaniu przestrzeni adresowej dla nowego procesu, trzeba teraz ponieść koszty obsługi TLB missów. Jeśli system operacyjny zmienia obecnie wykonywany proces często - ten koszt może być duży.
identyfikator przestrzeni adresowej - unikatowo identyfikuje każdy proces i jest używany do ochrony przestrzeni adresowej tego procesu. Używając identyfikatorów, przy odczycie wpisu z TLB sprawdzamy dodatkowo czy odnosi się do obecnie wykonywanego procesu poprzez porównanie identyfikatorów.
Dzięki użyciu identyfikatorów nie musimy czyścić TLB przy zmianie procesu. W ten sposób jeśli drugi proces, na który się przełączyliśmy, działa krótko, to po powrocie do pierwszego procesu część wpisów w TLB zostanie zachowana przyspieszy działanie procesu.
## Zadanie 8
:::success
Autor: Kacper Solecki
:::
**problem homonimów** - jeśli cache bazuje na wirtualnym adresie do tagowania i indeksowania to pojawia się problem gdy ten sam adres wirtualny odpowiada różnym adresom fizycznym. Przy odwołaniu do pamięci tym adresem wirtualnym cache może zwrócić dane z nieprawidłowego adresu fizycznego.
Możliwe rozwiązania:
1) Użycie indetyfikatora przestrzeni adresowej.
2) Czyszczenie cache'u przy zmianie kontekstu.
**problem synonimów** - z drugiej strony wiele różnych adresów wirtualnych może się odnosić do tego samego adresu fizycznego. Wtedy gdy program modyfikuje dane w pamięci będą one aktualizowane w cache tylko dla jednego z adresów wirtualnych.
Możliwe rozwiązania:
1) Czyszczenie cache'u przy zmianie kontekstu - ale to nie pomoże jeśli problem występuje w tej samej przestrzeni adresowej co też jest możliwe.
2) Cache w pełni asocjacyjny, nie większy niż rozmiar strony - wtedy adresy wirtualne mapowane do danego adresu fizycznego mają takie same bity CO.
3) Rozwiązania hardwarowe - mogą kosztować wiele cykli procesora