С явным отрывом первое место берёт "общий L3 cache с ~30ns latency на загрузку".
Поздравляем победителей 🥳🥳🥳
———
А теперь опишу, как я понимаю происходящее.
Если бы на дворе был, скажем, 2015 год, то Consumer действительно пошёл бы в L3 и нашёл там данные.
Во всяком случае, в серверных процессорах Intel того времени использовался так называемый inclusive L3 cache.
Кеш-линия при изменении должна была не только находиться в приватных кешах ядра (L1/L2), но и поддерживаться в синхронизированном состоянии в общем L3.
Где ее и находили бы все желающие.
———
Но начиная со Skylake-SP (2017) и по сей день используется non-inclusive L3 cache.
И дата флоу выглядит примерно так:
1. Producer загружает данные из DRAM, и они сразу попадают в приватные L2/L1 кеши. Копия в L3 при этом не создаётся.
2. Producer меняет данные (Modified), и в этот момент они находятся только в его L1/L2 кешах.
3. Consumer, живущий на другом ядре, запрашивает ту же кеш-строку и получает каскад промахов: L1 → L2 → L3.
Самих данных в L3 нет, но рядом работает Snoop Filter. Он хранит информацию в кешах каких ядер какие кеш-линии находятся.
В приватном кеше соседнего ядра мы и найдем искомые данные, потянув их напрямую в свой кеш, опять игнорируя запись в L3.
Такое событие называется HITM: линия найдена в Modified-состоянии в чужом приватном кеше.
Таким образом, данные попадают в L3 в основном при вытеснении из приватных кешей (eviction) и не синхронизируются ни при первоначальной загрузке из DRAM, ни при последующих изменениях.
———
Для контраста можно привести механизм TLB: при промахе Page Walker может дойти до DRAM, а затем сопоставление "
физ.адрес - вирт.адрес" каскадно заполняет все вышележащие уровни:PSC → STLB → dTLB.
———
Теперь к длительностям:
L1 hit: ~1ns
L2 hit: ~3-4ns
L3 hit: ~30-50ns
HITM: ~50-80ns
DRAM Local: ~80-100ns
DRAM Remote: 140-180ns
...
Выходит, что ответ в ~30ns выглядит немного оптимистично, а вот в 60ns вполне ок.
Почитать тут и тут.
———
Критика и уточнения приветствуются, хорошего дня!