Основні правила насправді досить прості. Там, де це стає складним, полягає в тому, як вони застосовуються до вашого коду.
Кеш працює на двох принципах: темпоральна локальність та просторова локальність. Перша - це думка, що якщо ви нещодавно використали певний фрагмент даних, вам, швидше за все, знадобляться незабаром. Останнє означає, що якщо ви нещодавно використовували дані за адресою X, вам, ймовірно, незабаром знадобиться адреса X + 1.
Кеш намагається пристосувати це шляхом запам'ятовування останніх часто використовуваних фрагментів даних. Він працює з кеш-лініями, як правило, розміром 128 байт або близько того, навіть якщо вам потрібен лише один байт, вся кеш-лінія, що містить його, потрапляє в кеш. Отже, якщо вам знадобиться наступний байт після цього, він уже буде в кеші.
А це означає, що ви завжди хочете, щоб ваш власний код максимально експлуатував ці дві форми місцевості. Не стрибайте всю пам'ять. Виконайте якомога більше роботи на одній невеликій площі, а потім перейдіть до наступної та виконайте там скільки завгодно робіт.
Простий приклад - обхід 2D масиву, який показав відповідь 1800 року. Якщо ви проходите рядок за часом, ви читаєте пам'ять послідовно. Якщо ви це зробите в стовпчику, ви прочитаєте один запис, а потім перейдете до зовсім іншого місця (початок наступного рядка), прочитайте один запис та ще раз перескочіть. І коли ви нарешті повернетесь до першого ряду, він більше не буде в кеші.
Те саме стосується коду. Стрибки або гілки означають менш ефективне використання кешу (оскільки ви не читаєте інструкції послідовно, а переходите на іншу адресу). Звичайно, малі заяви-if, ймовірно, нічого не змінять (ви пропускаєте лише кілька байт, тому ви все одно опинитесь у кешованій області), але виклики функцій зазвичай означають, що ви переходите до зовсім іншого адреса, яка може бути не кешована. Якщо тільки його не називали нещодавно.
Використання кеш-інструкцій, як правило, набагато менше проблеми. Що зазвичай потрібно хвилюватися - це кеш даних.
У структурі або класі всі члени викладаються безперервно, що добре. У масиві всі записи також викладаються безперервно. У пов'язаних списках кожен вузол виділяється у зовсім іншому місці, що погано. Загалом, покажчики, як правило, вказують на непов'язані адреси, що, ймовірно, призведе до пропуску кешу, якщо ви його знеструмите.
І якщо ви хочете використовувати декілька ядер, це може стати справді цікавим, як зазвичай, лише один процесор може мати будь-яку задану адресу в своєму кеші L1 одночасно. Тож якщо обидва ядра постійно отримують доступ до однієї адреси, це призведе до постійних промахів кешу, оскільки вони борються за адресу.