Podstawowe zasady są w rzeczywistości dość proste. Problematyczne jest to, jak stosują się do Twojego kodu.
Pamięć podręczna działa na dwóch zasadach: lokalności czasowej i lokalności przestrzennej. Pierwsza z nich polega na tym, że jeśli niedawno użyłeś określonej porcji danych, prawdopodobnie wkrótce będziesz jej ponownie potrzebować. To ostatnie oznacza, że jeśli ostatnio używałeś danych pod adresem X, prawdopodobnie wkrótce będziesz potrzebować adresu X + 1.
Pamięć podręczna próbuje to uwzględnić, zapamiętując ostatnio używane fragmenty danych. Działa z liniami pamięci podręcznej, zwykle o rozmiarze 128 bajtów, więc nawet jeśli potrzebujesz tylko jednego bajtu, cała linia pamięci podręcznej, która go zawiera, zostanie wciągnięta do pamięci podręcznej. Więc jeśli później będziesz potrzebować następującego bajtu, będzie on już w pamięci podręcznej.
A to oznacza, że zawsze będziesz chciał, aby Twój własny kod wykorzystywał te dwie formy lokalności w jak największym stopniu. Nie przeskakuj całej pamięci. Wykonuj tyle pracy, ile możesz na jednym małym obszarze, a następnie przejdź do następnego i wykonaj tam tyle pracy, ile możesz.
Prostym przykładem jest przechodzenie przez tablicę 2D, które pokazała odpowiedź z 1800 roku. Jeśli przechodzisz przez wiersz na raz, czytasz pamięć sekwencyjnie. Jeśli zrobisz to na podstawie kolumn, przeczytasz jeden wpis, a następnie przeskoczysz do zupełnie innej lokalizacji (początek następnego wiersza), przeczytasz jeden wpis i skoczysz ponownie. A kiedy w końcu wrócisz do pierwszego wiersza, nie będzie go już w pamięci podręcznej.
To samo dotyczy kodu. Skoki lub rozgałęzienia oznaczają mniej wydajne wykorzystanie pamięci podręcznej (ponieważ nie czytasz instrukcji po kolei, ale skaczesz na inny adres). Oczywiście małe instrukcje if prawdopodobnie niczego nie zmienią (pomijasz tylko kilka bajtów, więc nadal znajdziesz się w obszarze pamięci podręcznej), ale wywołania funkcji zwykle sugerują, że skaczesz do zupełnie innego adres, który nie może być zapisany w pamięci podręcznej. Chyba że został ostatnio wywołany.
Jednak użycie pamięci podręcznej instrukcji jest zwykle znacznie mniejszym problemem. To, o co zwykle musisz się martwić, to pamięć podręczna danych.
W strukturze lub klasie wszystkie składowe są rozmieszczone w sposób ciągły, co jest dobre. W tablicy wszystkie wpisy są również ułożone w sposób ciągły. Na listach połączonych każdy węzeł jest przydzielany w zupełnie innej lokalizacji, co jest złe. Wskaźniki na ogół wskazują na niepowiązane adresy, co prawdopodobnie spowoduje pominięcie pamięci podręcznej, jeśli ją wyłuskujesz.
A jeśli chcesz wykorzystać wiele rdzeni, może to być naprawdę interesujące, jak zwykle tylko jeden procesor może mieć dany adres w swojej pamięci podręcznej L1 na raz. Więc jeśli oba rdzenie stale uzyskują dostęp do tego samego adresu, spowoduje to ciągłe chybienia pamięci podręcznej, ponieważ walczą o adres.