Pamięć cache, wrzut na chomika listopad, Informatyka -all, INFORMATYKA-all, Informatyka-20 września 2004


Pamięć cache

Cache to mechanizm w którym ostatnio pobierane dane dostępne ze źródła o wysokiej latencji i niższej przepustowości są trzymane w pamięci o lepszych parametrach.

Cache jest elementem właściwie wszystkich systemów - współczesny procesor ma 2 albo 3 poziomy pamięci cache oddzielającej go od pamięci RAM. Dostęp do dysku buforowany jest w cache w pamięci RAM, a dokumenty HTTP są cache'owane przez programy http proxy oraz przez przeglądarkę.

ZADANIA

Systemy te są tak wydajne dzięki lokalności odwołań - jeśli nastąpiło odwołanie do pewnych danych, jest duża szansa że w najbliższej przyszłości będą one potrzebne ponownie. Niektóre systemy cache próbują przewidywać które dane będą potrzebne i pobierają je wyprzedzając żadania. Np. cache procesora pobiera dane w pakietach po kilkadziesiąt czy też więcej bajtów, cache dysku zaś nawet do kilkuset kilobajtów kolejnych właśnie czytanego pliku.

Niektóre systemy pamięci cache umożliwiają informowanie systemu na temat charakteru danych by umożliwiać bardziej efortywny caching. Służy temu np. wywołanie systemowe madvise

Cache - (pamięć buforowa, pamięć notatnikowa lub pamięć podręczna) to rodzaj bardzo szybkiej pamięci podręcznej, służącej do buforowania danych, przesyłanych pomiędzy twardym dyskiem a pamięcią operacyjną; cache twardego dysku wywiera bardzo istotny wpływ na wydajność całego systemu; w sposób niezauważalny dla użytkownika system przenosi dane do pamięci cache i kopiuje je na twardy dysk dopiero w momencie, kiedy procesor jest mniej zajęty; pamięć cache przesyła dane do procesora około 100 000 razy szybciej, niż twardy dysk; stąd proporcjonalnie do wielkości pamięci cache zwiększa się również wydajność systemu; łatwo to zauważyć po różnicy w szybkości działania systemu, kiedy dysponuje on 32 MB pamięci operacyjnej, a kiedy w systemie dostępnych jest tylko 8 lub 16 MB.

Typy organizacji i informacji w pamięci CACHE: 1. Asocjacyjna 2. Bezpośrednia 3. Zbiorowe odwzorowanie asocjacyjne

Zasady lokalności CACHE: 1. Lokalność przestrzenna - dane umieszczane są stosunkowo blisko siebie 2. Lokalność czasowa - dane pobierane są z pamięci wielokrotnie 

TYPY

cache poziomu pierwszego(32 kb) i drugiego 512KB trzeciego (1024KB) czwartego(2048KB)

Cache (8kB pamięci podręcznej danych i 8kB pamięci podręcznej kodu programu), pamięć Cache

0x01 graphic

32-bajtowe (256 bitowe); Jeśli podczas operacji odczytu poszukiwanych danych nie ma w posiada komórki podręcznej pamięci wewnętrznej, procesor sięga po nie do zewnętrznej pamięci Cache (zwanej w tym przypadku pamięcią drugiego poziomu).

Zastosowanie funkcji seryjnego zapisu i odczytu (Burst Write and Read Function); Seryjny odczyt polega na jednokrotnym wystawieniu na szynie adresowej (podczas pierwszego cyklu zegarowego), adresu odczytywanego słowa z pamięci RAM, a następnie w czterech kolejnych cyklach zegarowych odczytanie czterech 64-bitowych danych, w ten sposób, w ciągu pięciu cykli

0x01 graphic

zegarowych zostaje skompletowane 256-bitowe słowo danych, ładowane do 256-bitowej komórki pamięci Cache.

Pamięć podręczna Cache może pracować w trybie Write-Back i Write- Trough. Tryb Write-Back (z opóźnionym zapisem) polega na zapisie danych najpierw do pamięci Cache a dopiero później dane przepisywane są do pamięci RAM. Tryb Write-Trough dotyczy jednoczesnego zapisu danych do pamięci Cache i RAM.
Struktura super skalarna i przetwarzanie danych dwu potokowe

Oprócz standardowej pamięci operacyjnej procesor dysponuje jeszcze szybką pamięcią (cache memory) służąca do przechowywania ostatnio używanych informacji.

Znaczenie

Dane aktualnie używane są trzymane w szybszej pamięci, natomiast te aktualnie niepotrzebne w wolniejszej, ale większej. Ponieważ różnice w czasie dostępu między kolejnymi poziomami są często rzędu 10:1, dobre wykorzystanie właściwości pamięci cache ma zazwyczaj większe znaczenie niż liczba cykli procesora koniecznych do wykonania algorytmu.

Cel stosowania pamięci cache w procesorach

0x01 graphic


    Aby określić cel stosowania pamięci podręcznej cache, należy w skrócie omówić zasadę działania mikroprocesora.

    Jest on układem cyfrowym taktowanym przez sygnał zegarowy, który realizuje zadany program - ciąg rozkazów umieszczony w pamięci operacyjnej. Program ma zwykle zadanie przetworzenia określonych danych pobranych z pamięci (lub urządzeń zewnętrznych), oraz zapisanie wyników ich przetwarzania, też w pamięci (lub przekazanie do urządzeniach zewnętrznych). Schemat blokowy mikroprocesora przedstawiono na rysunku 1.1. Na schemacie znajduje się też  blok pamięci operacyjnej, który fizycznie stanowi oddzielny układ.

Rys. 1.1 Schemat blokowy mikroprocesora.
 

0x01 graphic

OZNACZENIA

RAM (Random Acces Memory) - pamięć operacyjna
BU (Bus Unit) - układ zarządzający magistralami
AU (Addresing Unit) - układ obliczania adresu połączony z
MMU (Memory Management Unit) układem zarządzania pamięcią
IU (Instruction Unit) - dekoder instrukcji
EU (Execution Unit) -moduł wykonawczy zawiera
ALU (Aritmetic-Logic Unit) jednostkę arytmetyczno-logiczną
FPU (Floating Point Unit) jednostkę zmiennoprzecinkową

Połączenie mikroprocesora z pamięcią operacyjną realizuje się za pomocą dwóch magistral adresowej i
danych. Do sterowania ruchem na tych magistralach wykorzystuje się zbiór sygnałów sterujących.

Realizacja programu przez taki układ przebiega następująco:

 Kod rozkazów jest odczytywany z pamięci RAM i umieszczany w kolejce instrukcji.

 Poszczególne instrukcje (słowa binarne) trafiają z kolejki do dekodera IU, który rozkodowuje rozkazy przeznaczone do wykonania. Wykorzystuje przy tym informacje o sposobie kodowania rozkazów zawarte w pamięci stałej ROM umieszczonej w strukturze procesora.

 Zależnie od rozkazu dekoder często musi wydzielić z kodu instrukcji zawarte w niej argumenty, lub adresy danych, które procesor będzie wykorzystywał. Są one przesyłane odpowiednio do bloku wykonującego instrukcje EU i bloku adresowego AU.

 Blok adresowy AU i zarządzania pamięcią MMU wypracowuje na tej podstawie odpowiednie sygnały i dane przekazywane do bloku zarządzania magistralami BU. Po wystawieniu adresu na magistrali adresowej generowane są sygnały sterujące, które powodują odczyt danych z pamięci - układ pamięci wystawia dane na magistrali danych.

 Dane są przekazywane do bloku wykonującego instrukcje lub (jeśli są kodami następnych rozkazów programu do kolejki instrukcji).

 Blok wykonujący instrukcje EU zawiera jednostkę arytmetyczno-logiczną ALU, która dokonuje porównań lub działań matematycznych na argumentach stałoprzecinkowych. Argumenty zmienno-przecinkowe są przetwarzane w jednostce do tego celu wyspecjalizowanej FPU.

 Wyniki przetwarzania trzeba często zapisać w pamięci pod określonym adresem - blok wykonujący instrukcje przekazuje odpowiednie dane do bloku zarządzania pamięcią i bloku sterującego magistralami.     Wszystko musi być odpowiednio synchronizowane w czasie, dlatego układ wykonujący instrukcje EU wypracowuje też różne sygnały sterujące, przez które ma możliwość wpływu na pracę innych bloków. Układ wykonujący instrukcje często też przechowuje wyniki pośrednie przetwarzania danych we własnych rejestrach. Jednak aby nie zaciemniać schematu na rys. 1.1 nie przedstawiano szczegółowej budowy wyróżnionych bloków.

Szybkość wykonywania programu zależy w znacznej mierze od czasu dostępu procesora do układu pamięci operacyjnej. Nie bez znaczenia jest także pojemność pamięci (ile danych można w niej zapisać). Stosowane we współczesnych komputerach wielozadaniowe systemy operacyjne umożliwiają uruchamianie wielu programów jednocześnie. Dobrze jest więc gdy procesor ma do dyspozycji dużą pamięć operacyjną RAM. Ważnym czynnikiem pozostaje też koszt zastosowanego układu pamięci. Naturalnie w przypadku praktycznego systemu musi on być jak najniższy.

Istnieją wzajemne zależności pomiędzy wszystkimi opisywanymi wyżej parametrami.
 

 mniejszy czas dostępu - większy koszt

 większa pojemność - większy czas dostępu


    Z tego wynika, że nie jest możliwe wyprodukowanie idealnej pamięci o maksymalnie dużej pojemności, a przy tym małym czasie dostępu i minimalnym koszcie. Możliwe jest budowanie szybkich układów, ale stosunkowo drogich i o małej pojemności. Istnieją też duże pamięci o małych kosztach w przeliczeniu na bajt, ale cechujące się mniejszą efektywnością w zakresie czasu dostępu.

We współczesnych procesorach stosuje się rozwiązanie kompromisowe, polegające na zastosowaniu pamięci wewnętrznej dwupoziomowej. Mikroprocesor wyposaża się we względnie dużą i wolniejszą pamięć główną, oraz w mniejszą ale szybszą pamięć podręczną cache. Ilustruje to schemat blokowy przedstawiony na rysunku 1.2. Takie rozwiązanie pozwala na korzystanie z pamięci o dużej pojemności, jednocześnie możliwe jest umieszczenie najpotrzebniejszych danych, w szybkiej pamięci podręcznej.
Pamięć podręczna zawiera kopię części zawartości pamięci głównej. Gdy procesor zamierza odczytać słowo z pamięci, najpierw następuje sprawdzenie, czy słowo to nie znajduje się w pamięci podręcznej. Jeśli tak, to słowo to jest szybko dostarczane do procesora. Jeśli nie, to blok pamięci głównej RAM zawierający określoną liczbę kolejnych słów jest wczytywany do pamięci podręcznej, a następnie potrzebne słowo (zawarte w tym bloku) jest dostarczane do procesora. Następne odwołania do tego samego słowa i sąsiednich zawartych w przepisanym bloku będą realizowane już znacznie szybciej.
    Organizacja współpracy procesora z takimi pamięciami wymaga zastosowania dodatkowego układu - kontrolera cache, który steruje tym procesem.

Rys 1.2 Podłączenie cache do procesora

0x01 graphic

Rys 1.3 Algorytm dostępu procesora do pamięci

0x01 graphic

    Efektywność stosowania cache zależy w znacznej mierze od sposobu ułożenia kodu programów i danych pobieranych z pamięci przez mikroprocesory. Zwykle kod i dane nie są "porozrzucane" przypadkowo po całej dostępnej przestrzeni adresowej w pamięci RAM. Większość odwołań do pamięci w trakcie wykonywania programu odbywa się przez pewien czas pracy mikroprocesora w wąskim obszarze. Zjawisko to jest określane mianem lokalności odniesień.

Lokalność odniesień można uzasadnić intuicyjnie w następujący sposób:

    Oczywiście w długim czasie wykonywania programu procesor potrzebuje dane rozmieszczone w różnych odległych miejscach pamięci. Zwykle jednak, po wykonaniu skoku następne odniesienia odbywają się już lokalnie. Przepisanie bloku kolejnych komórek pamięci do szybkiego układu cache może więc skutecznie przyspieszyć dostęp do pamięci.

    Na drodze rozważań teoretycznych i różnych symulacji wyznaczono rozmiar tego wąskiego obszaru, do którego odwołuje się procesor. Stwierdzono, iż można przyjąć z prawdopodobieństwem 0,9 że większość odwołań do pamięci mieścić się będzie w bloku o rozmiarze nie przekraczającym 16 kB. Potwierdzają to praktyczne testy. Tak więc wystarczy naprawdę mały układ pamięci podręcznej cache, aby skutecznie przyspieszyć działanie mikroprocesora. Rozmiary całej pamięci RAM współczesnych komputerów są rzędu 64 - 128 MB, podczas gdy rozmiary cache w popularnych procesorach to 8 - 512 kB.

Przedstawione wyżej schematy przedstawiają układ cache w dużym uproszczeniu. Istnieje możliwość zastosowania rozwiązania, w którym ten pierwszy poziom cache przyspiesza dostęp do następnego układu pamięci podręcznej, ten z kolei może wymieniać dane jeszcze z następnym, lub z pamięcią główną RAM.  W niektórych stosowanych obecnie układach procesorowych można wyróżnić aż trzy poziomy pamięci podręcznej cache. W praktyce stosuje się wielopoziomową pamięć podręczną.  W stosowanych obecnie rozwiązaniach można wyróżnić następujące poziomy pamieci podręcznej.

Pamięć podręczna najniższego poziomu (L1) jest stosunkowo mała, ale dane w niej zgromadzone są szybko dostępne dla procesora. W wypadku braku potrzebnych w danym momencie danych (braku trafienia), następuje odwołanie do pamięci kolejnych, wyższych poziomów. Po ich odczycie następuje przepisanie do niższych poziomów, tak by były szybciej dostępne w kolejnych odwołaniach. Jeśli dane nie są aktualnie buforowane w cache, następuje odczyt bloku pamięci głównej RAM, który je zawiera i wymiana zawartości cache.
Pamięci niższych poziomów mogą mieć mniejszą pojemność i być bardziej efektywne. Procesor może szybko odczytywać mniejsze porcje danych w jednym cyklu zegara. Wyższe poziomy cache mają większe pojemności, dzięki czemu odwołania do RAM mogą odbywać się rzadziej. Można też w jednym odczycie przepisać większą porcję danych z RAM. Dobrze to obrazuje schemat przepływu danych w procesorze ITANIUM (rys. 1.3). Na tym schemacie pokazano też blok rejestrów procesora (Register File), w których zapisuje on odczytane z pamięci argumenty i wyniki działania rozkazów.

Rys 1.3 Schemat przepływu danych w procesorze ITANIUM
 

0x01 graphic

    Jak wynika z rysunku, odczyt danych z pamięci RAM może odbywać się większymi porcjami z prędkością 2.1 GB na sekundę. Dzięki zastosowaniu odpowiedniej magistrali BSB (Back Side Bus) przepływ danych z pamięci podręcznej poziomu L3 do L2 odbywa się z prędkością 16 bajtów w ciągu jednego cyklu zegara. Możliwy jest również odczyt pojedynczych słów bezpośrednio do rejestrów co zaznaczono przerywaną linią. Z cache L2 procesor odczytuje już w jednym cyklu bloki danych wielkości 32 B. Pamięć poziomu L1 najbardziej efektywna w zakresie czasu dostępu, udostępnia procesorowi już pojedyncze słowa - zmienne przetwarzane w kolejnych rozkazach.

Schemat 1.3 najpełniej obrazuje korzyści jakie daje układ pamięci podręcznych cache.

Ważnym zagadnieniem, jest podział pamięci podręcznej na oddzielny blok dla kodu programu i oddzielny blok dla danych. W taki sposób jest podzielona pamięć poziomu L1 procesora ITANIUM - rys 1.3. Pamięć cache poziomów L2 i L3 jest już wspólna dla rozkazów i danych.
W wielu (szczególnie starszych) procesorach wykorzystuje się również jednolitą pamięć podręczną poziomu L1. Takie rozwiązanie też posiada pewne zalety. Poniżej przedstawiono korzyści płynące z zastosowania pamięci oddzielnej i jednolitej.

Pamięć oddzielna kod i dane
Eliminowana jest rywalizacja o dostęp do pamięci między układem pobierania i dekodowania rozkazów w procesorze, a jednostką wykonującą w tym samym czasie inne, poprzednio pobrane rozkazy, które mogą wymagać odczytu pewnych zmiennych z cache. Ma to szczególne znaczenie w przypadku procesorów superskalarnych, w których kilka rozkazów jest wykonywanych równolegle. Dlatego we współczesnych procesorach poziom pamięci podręcznej L1 jest zawsze dzielony na blok danych i instrukcji.

Pamięć łączna dla kodu i danych
Poprawia się współczynnik trafień w tak zorganizowanej pamięci podręcznej, dzięki temu, że  naturalnie równoważy się zapotrzebowanie na przechowywanie rozkazów i danych. Jeśli na przykład program wymaga ciągłego pobierania rozkazów i w małym stopniu korzysta z danych, dostępna pamięć podręczna zapełni się w większości rozkazami. Oddzielna cache dla danych w takiej sytuacji pozostałaby nie wykorzystana.
Drugą zaletą jest to, że upraszcza się układ procesora - łatwiej jest zrealizować w jego strukturze jeden bufor pamięci cache niż dwa.

Sposoby dołączania pamięci cache do procesora

0x01 graphic


    Układ cache jest w obecnych procesorach ściśle związany z ich strukturą - właściwie poziom L1 fizycznie stanowi integralną część mikroprocesora.  Jednak aby łatwiej było przedstawić zasadę działania i sposoby dostępu procesora do pamięci podręcznej, ta część programu traktuje je ją jako oddzielny blok logiczny, dołączony do mikroprocesora, nie zajmując się jej fizycznym umiejscowieniem. Pisząc o sposobach dołączania, mamy więc na myśli sposób umieszczenia bloku cache na drodze procesor - pamięć.

    Obecnie stosuje się trzy podstawowe sposoby dostępu procesora do pamięci podręcznej.

0x01 graphic