Использует ли процессор x86_64 одни и те же строки кэша для связи между двумя процессами через общую память?

Как известно, все уровни кэша L1/L2/L3 на современном x86_64 практически проиндексированы, физически помечены. И все ядра обмениваются данными через кэш последнего уровня - cache-L3, используя согласованный с кэшем протокол MOESI/MESIF через QPI/HyperTransport.

Например, процессор семейства Sandybridge имеет 4 - 16-сторонний кэш L3 и page_size 4 КБ, что позволяет обмениваться данными между параллельными процессами, которые выполняются на разных ядрах через общую память. Это возможно, потому что кэш L3 не может содержать ту же область физической памяти, что и страница процесса 1, и как страница процесса 2 одновременно.

Означает ли это, что каждый раз, когда процесс-1 запрашивает одну и ту же область общей памяти, процесс-2 сбрасывает свои строки кэша страницы в ОЗУ, а затем процесс-1 загружает ту же область памяти, что и строки кэша страницы в виртуальном пространстве процесса-1? Это действительно медленно или процессор использует некоторые оптимизации?

Использует ли современный процессор x86_64 одни и те же строки кэша, без каких-либо сбросов, для связи между двумя процессами с различными виртуальными пространствами через общую память?

Процессор Intel Sandy Bridge - кеш L3:

  • 8 МБ - размер кеша
  • 64 B - размер строки кэша
  • 128 K - строки (128 K = 8 МБ / 64 B)
  • 16-позиционная
  • 8 K - количество наборов путей (8 K = 128 K линий / 16-полосный)
  • 13 бит [18:6] - виртуального адреса (индекса) определяет номер текущего набора (это тег)
  • 512 K - каждый из них (виртуальный адрес / 512 K) конкурирует за один и тот же набор (8 МБ / 16 направлений)
  • младшие 19 битов - значимы для определения текущего номера набора

  • 4 КБ - стандартный размер страницы

  • только младшие 12 битов - одинаковые в виртуальных и физических адресах для каждого адреса

У нас есть 7 пропущенных битов [18:12] - т.е. нам нужно проверить (7^2 * 16-way) = 1024 строки кэша. Это то же самое, что и кэш с 1024 путями - так что это очень медленно. Означает ли это, что кэш L3 (физически проиндексирован, физически помечен)?

Сводка пропущенных бит в виртуальном адресе для тега (размер страницы 8 КБ - 12 бит):

  • L3 (8 МБ = 64 B x 128 K строк), 16-полосный, 8 K наборов, тег 13 битов [18:6] - пропущено 7 бит
  • L2 (256 КБ = 64 B x 4 K строк), 8-полосный, 512 наборов, тег 9 бит [14:6] - пропущено 3 бита
  • L1 (32 КБ = 64 В x 512 строк), 8-полосная, 64 набора, метка 6 битов [11:6] - без пропущенных битов

Так должно быть:

  • L3 / L2 (физически проиндексированный, физически помеченный), используемый после поиска TLB
  • L1 (практически проиндексирован, физически помечен)

введите описание изображения здесь

1 ответ

Решение

Это возможно, потому что кэш L3 не может содержать ту же область физической памяти, что и страница процесса 1, и страницу процесса 2 одновременно.

А что? Если оба процесса имеют сопоставленную страницу, они могут одновременно попасть в кэш для одной и той же строки физической памяти.

Это часть преимуществ многоядерных проектов Intel, использующих большие инклюзивные кэш-памяти третьего уровня. Для согласованности требуется только проверка тегов L3, чтобы найти строки кэша в состоянии E или M в кэше L2 или L1 другого ядра.

Получение данных между двумя ядрами требует только обратной записи в L3. Я забыл, где это задокументировано. Может быть, http://agner.org/optimize/. Процессоры до Nehalem, у которых были отдельные кэши для каждого ядра, я думаю, что для согласованности пришлось использовать DRAM. IDK, если данные могут быть отправлены непосредственно из кеша в кеш по тому же протоколу, который использовался для обнаружения проблем когерентности.


Одна и та же строка кэша, сопоставленная с разными виртуальными адресами, всегда будет находиться в одном и том же наборе кэша L1. См. Обсуждение в комментариях: кэши L2 / L3 физически индексируются, а также помечаются физически, поэтому наложение имен никогда не является проблемой. (Только L1 может получить выигрыш в скорости от виртуальной индексации. Промахи кэша L1 не обнаруживаются до тех пор, пока не закончится преобразование адреса, поэтому физический адрес готов вовремя для проверки кэшей более высокого уровня.)

Также обратите внимание, что обсуждение в комментариях неправильно упоминает Skylake, снижая ассоциативность кэша L1. Фактически, это кэш Skylake L2, который менее ассоциативен, чем раньше (4-сторонний, по сравнению с 8-разрядным в SnB/Haswell/Broadwell). L1 по-прежнему 32-килобайтный, как всегда, 8-сторонний: максимальный размер для той ассоциативности, которая удерживает биты адреса выбора страницы вне индекса. Так что нет никакой загадки в конце концов.

Также см. Другой ответ на этот вопрос о HT-потоках на том же ядре, обменивающихся данными через L1. Я сказал больше о способах кэширования и установках там. (И благодаря Voo, я просто исправил это, чтобы сказать, что индекс кэша выбирает набор, а не путь.:P)

Другие вопросы по тегам