Вы должны изучить протоколы когерентности кэша, такие как MESI и его расширения MOESI и MESIF.
В этих протоколах каждая строка кэша по сути представляет собой конечный автомат, переходящий из одного состояния в другое в зависимости от того, что делает его собственный процессор, а также от того, какие сообщения он отслеживает на шине.Контроллеры кэша контролируют транзакции шины памяти и соответственно обновляют состояния линий кэширования, отсюда и название «snoopy cache».
В MESI линия кэширования может иметь четыре состояния: Modified , Exclusive , Shared и Invalid .
Мы можем пройтись по вашему примеру, когда два ядра хотят записывать в одну и ту же кэш-строку и видеть с очень высокой-уровень, почему этот протокол не приведет к неверным результатам.
Предположим, что оба ядра начинаются с отсутствия строки кэша и что они сначала читают строку кэширования перед ее изменением.
1) Ядро1 хочет прочитать строку кэша, поэтому он передает BusRd , получает строку кэша из памяти и переходит к Exclusive .
2) Core 2 также хочет прочитатькешлайн, поэтому он передает BusRd .Ядро 1 отвечает строкой кеша в FlushOpt , и оба ядра переходят в Shared .
3) Ядро 1 хочет записать в кеш-линию, поэтому оно передает BusUpgr и переходы на Модифицированные .Core 2 видит BusUpgr и переходит в Invalid .
4) Core 2 хочет записать в кеш-линию, но он Invalid , поэтому он выдает BusRdX и переходы на Изменено .Core 1 отслеживает BusRdX и передает Flush перед переходом на Invalid . Flush наблюдается ядром 2 и контроллером памяти, который записывает значение обратно в память.
Поскольку операция записи на одном ядре делает недействительными копии строк кэша на других ядрах, линия кэширования будетдолжны быть восстановлены с последним значением.Таким образом, нет расы.:)