📌 Cache
Cache — сверхбыстрая энергозависимая память, предназначенная для временного хранения данных и инструкций, к которым CPU или GPU обращаются чаще всего. Используется для компенсации разницы скоростей между процессором и основной памятью (RAM), минимизации задержек при доступе к данным, повышения пропускной способности вычислительной системы.
🧠 Как работает
Архитектура и уровни
Cache обычно многоуровневая:
- L1 (Level 1): самый быстрый и маленький (типично 16–128 КБ на ядро), разделён на data/instruction (D/I-кэш), расположен максимально близко к CPU.
 - L2 (Level 2): больше (256 КБ – 2 МБ на ядро или общий для кластера), чуть медленнее L1.
 - L3 (Level 3): общий для нескольких ядер, объём до десятков мегабайт, заметно медленнее L2, соединён через отдельную Bus или Ring bus.
 
Cache реализуется на SRAM, что обеспечивает доступ в несколько наносекунд (против десятков-сотен для DRAM).
Принцип работы
- Принцип локальности: данные/инструкции, которые недавно использовались или физически близки к используемым, скорее всего понадобятся снова.
 - Кэширование блоков (lines): данные копируются из RAM целыми строками (обычно 32–128 байт).
 - Маппинг: прямая (direct-mapped), полностью ассоциативная (fully associative), сета-ассоциативная (set-associative) схемы.
 - Стратегии замещения: LRU, FIFO, Random, PLRU и др.
 - Управление когерентностью: для многоядерных CPU реализуется MESI/MOESI протоколы.
 
Последовательность обращения:
- CPU делает запрос к адресу данных.
 - Cache Controller проверяет, есть ли строка с нужным адресом (“hit”).
 - Запись реализуется как write-through или write-back (с отложенной записью в RAM).
 
flowchart TD CPU[[CPU]] -->|Address| L1[L1 Cache] L1 -->|Miss| L2[L2 Cache] L2 -->|Miss| L3[L3 Cache] L3 -->|Miss| RAM[RAM] L1 -->|Hit| CPU L2 -->|Hit| L1 L3 -->|Hit| L2
⚙️ Где применяется
- 
Внутри процессоров (CPU, GPU, DSP), микроконтроллеров (MCU), FPGA.
 - 
Серверы, рабочие станции, встраиваемые и мобильные платформы.
 - 
Специализированные ускорители (AI accelerator, NIC).
 - 
Кэш-директории и snoop-фильтры в многопроцессорных и NUMA-системах.
 
✅ Преимущества
- 
Минимизация задержек при доступе CPU к данным и инструкциям.
 - 
Значительное повышение производительности без роста частоты/энергопотребления.
 - 
Уменьшение нагрузки на RAM и Memory Bus.
 - 
Масштабируемость: возможность увеличивать объём/уровни кэша для разных классов устройств.
 - 
Повышение энергоэффективности вычислений.
 
❌ Недостатки
- 
Заметная стоимость производства из-за использования SRAM (дороже DRAM).
 - 
Осложнение архитектуры: многоканальность, когерентность, кэш-линии, блокировки.
 - 
Сложные сценарии гонок/когерентности в многоядерных системах (snoop, false sharing).
 - 
Уязвимость к ряду атак по сторонним каналам (Spectre, Meltdown, Flush+Reload).
 - 
Ограниченный объём (физически невыгодно делать большие кэши).
 - 
Влияет на критический путь микросхемы (добавляет задержки между этапами pipeline).
 
🔗 Связанные технологии
SRAM, DRAM, CPU, GPU, MCU, L1, L2, L3, MESI, MOESI, NUMA, Memory Bus, Pipeline, RAM, Write-back, Write-through, AI accelerator
Резюме
Cache — ключевой компонент, позволяющий резко повысить производительность вычислительных систем за счёт минимизации времени доступа CPU/GPU к часто используемым данным и инструкциям. Многоуровневая структура (L1, L2, L3), использование быстрого SRAM, протоколы когерентности и оптимизация под реальные паттерны обращений позволяют кэшу быть эффективным буфером между медленной RAM и высокоскоростным ядром процессора. Главные минусы: стоимость, сложность поддержки когерентности, ограничение по объёму и атаки по сторонним каналам.
Примеры кода
C: Моделирование кэш-промахов
#include <stdio.h>
#define SIZE 4096*1024
 
int arr[SIZE];
 
int main() {
    long long sum = 0;
    for (int stride = 1; stride <= 1024; stride *= 2) {
        for (int i = 0; i < SIZE; i += stride)
            sum += arr[i];
        printf("Stride: %d, Sum: %lld\n", stride, sum);
    }
    return 0;
}Данный код иллюстрирует зависимость промахов кэша от размера stride.
Ассемблер: чтение данных с проверкой попадания в L1
section .bss
    buffer resb 64
 
section .text
    global _start
_start:
    mov eax, [buffer]    ; Чтение кэш-линии из памяти (возможен L1 hit)
    add eax, 1
    mov [buffer], eax    ; Запись в ту же кэш-линию
    mov eax, 1
    int 0x80C: определение размеров кэша CPU в Linux
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    system("lscpu | grep 'cache'");
    return 0;
}Источники: Intel® SDM, ARM Architecture Reference Manual, osdev.org, Википедия, habr.com, спецификации JEDEC, публикации ACM/IEEE по архитектуре процессоров.