Z tego artykułu dowiesz się:
- Czym jest pamięć podręczna procesora.
- Jak optymalizować pod nią kod.
- Przeczytasz o zasadzie lokalności i jej rodzajach.
- Zobaczysz na przykładach, jak prawidłowo wykorzystać lokalność.
Spis treści
- Pamięć podręczna procesora i jej warstwy
- Rodzaje lokalności
- Jak pisać kod przyjazny dla pamięci podręcznej
- Jak lokalność wpływa na nasz kod
- Podsumowując znaczenie pamięci podręcznej procesora
Współczesne procesory posiadają własne struktury pamięci. Najniższą są rejestry, które mogą przenosić dane w pojedynczych cyklach zegara. Ta najniższa struktura jest kosztowna w produkcji, przez co jest też najmniejsza, ale za to niezwykle szybka. Większość rdzeni komputera posiada jedynie kilkadziesiąt takich rejestrów.
Wziąwszy pod uwagę całą dostępną pamięć w komputerze, to na drugim końcu tego spektrum znajduje się pamięć RAM. Jest ona oczywiście wielokrotnie większa, tania w produkcji i wymaga setek cykli, aby przekazać do procesora te same dane.
Pamięć podręczna procesora i jej warstwy
Aby wypełnić lukę między szybką i drogą pamięcią a wolną i tanią istnieje tak zwana pamięć podręczna procesora, kolejno podzielona na trzy warstwy: L1, L2, L3.
- L1 to najszybsza dostępna pamięć podręczna. Jest znacznie szybsza niż inne warstwy pamięci podręcznej lub RAM. Jednakże jest również znacznie mniejsza w pojemności. W dzisiejszych czasach pamięć L1 waha się od 256 KB do nie więcej niż 1 MB, ale za to każdy rdzeń otrzymuje własną dedykowaną pamięć podręczną L1.
- Pojemność L2 jest kilka razy większa niż L1. Współczesne procesory posiadają pamięć L2 w rozmiarach około 6 MB do nawet 10 MB. L2 nie jest jednak tak szybka jak L1, znajduje się dalej od rdzeni i jest przez nie współdzielona.
- .L3 jest znacznie większa niż L1 i L2. W procesorach i9 Intela osiąga 16 MB, natomiast w niektórych procesorach AMD osiąga nawet 64 MB. Jest to jednak również najwolniejsza warstwa pamięci w procesorze.
Jeśli procesor nie może znaleźć danych w pamięci L1, to szuka ich w pamięci L2. Jeśli tam ich nie znajduje, to uderza do pamięci podręcznej L3, a jeśli tam również ich nie ma, to do pamięci głównej. Każde z chybionych przeszukań pamięci przedłuża czas operacji i przekłada się na zmniejszoną wydajność. Dodatkowo każdy kolejny poziom w hierarchii pamięci jest wolniejszy od poprzedniego, przez co także każde kolejne chybienie jest dodatkowo wolniejsze.
W dalszej części artykułu będziemy dość często odnosić się do takich wydarzeń używając właśnie pojęć „trafienie/chybienie”.
Odpowiednie buforowanie użytecznych danych pomaga zapobiec chybieniom. W tym celu należy wykorzystać pewną podstawową właściwość programów komputerowych.
Tą właściwością jest tak zwana zasada lokalności (ang. locality). Lokalność zakłada umieszczanie powiązanych danych w pamięci blisko siebie celem wydajniejszego buforowania. Programy z dobrą lokalnością będą skuteczniej uzyskiwać dostęp do tego samego zestawu danych z niższych poziomów hierarchii pamięci i dzięki temu będą działać szybciej. Wysoki poziom lokalności może oznaczać nawet dwudziestokrotnie szybsze obliczenia.