Если я правильно прочитал вопрос, MESI - это просто красная сельдь здесь:
0 reg = load(&counter);
counter
теперь загружено в регистр процессора.
1 reg = reg + 1; reg = load(&counter);
Первый процессор увеличил значение, второй загрузил старый.
2 store(&counter, reg); reg = reg + 1;
Первый процессор хранит значение, второй увеличивает его устаревшее.
3 store(&counter, reg);
Второй процессор хранит результат расчета на основе устаревшего значения.
Пока ясно. Теперь, как это изменится, если добавить MESI-состояния:
0 reg = load(&counter);
counter
находится в кэше ЦП 1, помечено E
.
1 reg = reg + 1; reg = load(&counter);
counter
все еще находится в кэше ЦП 1, но также загружается в кэш ЦП 2. Таким образом, обе строки кэша должны быть отмечены как S
2 store(&counter, reg); reg = reg + 1;
Теперь counter
сохраняется обратно в кеш. Таким образом, кэш ЦП 1 должен быть помечен как M
, а кэш ЦП 2 признан недействительным (помечен как I
).
3 store(&counter, reg);
Поскольку кэш ЦП 2 признан недействительным, его необходимо обновить, прежде чем может произойти операция store
, что, в свою очередь, требует, чтобы кэш ЦП 1 был записан обратно в память до (конечно).
Но все, что делается сейчас, значение в reg
по-прежнему рассчитывалось на основе устаревшего значения и все равно перезаписывает (теперь обновленное) значение в кеше ...
Добавление окончательной детали: после операции кэш ЦП 2 будет помечен M
, а кэш ЦП 1 I
.