2015-09-06 2 views
2

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

Я пытаюсь понять последствия этого сценария.

ответ

2

Когерентность кеша поддерживается на уровне детализации, обычно 64B в большинстве процессоров в наши дни. Ядро, выполняющее модификацию, сначала запрашивает право собственности на всю линию, а это означает, что все остальные ядра должны аннулировать свои копии (если они есть). Любое другое ядро, пытающееся прочитать, будет запрашивать эту строку, что приведет к отправке snoop в модифицирующее ядро. Оттуда у вас есть два варианта:

  1. Либо ядро ​​модифицирования завершена последовательность чтение-модификация-запись, и линия находится в кэше с последними изменёнными данными - в этом случае сыщик будет инициировать WB последовательности , обновленная строка станет доступной для всех, а второе ядро ​​может прочитать любой байт из нее.

  2. Модифицирующее ядро ​​приобрело линию через нагрузку, но ее хранилище все еще не произвело изменения (что возможно, поскольку магазины обычно выполняются гораздо позже в трубе, в то время как нагрузки часто выполняются спекулятивно). В этом случае ядро ​​должно защищать линию от слежки, как правило, путем реализации внутреннего замка для таких операций. Обратите внимание, что на x86, например, для большинства операций атомарного чтения-изменения-записи требуется префикс блокировки. Также обратите внимание, что нормальная последовательность read + write (non atomic) просто потеряла бы линию в этой точке и снова приобрела ее для магазина, тем самым потеряв согласованность.

Edit: следующий комментарий Павла, это действительно возможно разработать систему кэширования, которая позволяет отслеживать суб-линии зернистость. Это в основном означает развязку базового блока протокола MESI от базового размера блока, используемого для кеширования, вам нужно будет добавить бит состояния для каждого поднабора (но все равно использовать один тег для всех), сделать недействительными только локальные подмножества и в конечном итоге сделать слияние каким-то образом, чтобы восстановить полную линию. Однако накладные расходы сделают это довольно редким явлением, и я не знаком с коммерческими процессорами, которые делают все это, чтобы избежать ложного обмена. В любом случае, поскольку такой дополнительный блок, вероятно, не будет байтом, исходный вопрос по-прежнему применяется для байтов в одном блоке.

+0

«Потеря согласованности», вероятно, должна «потерять атомарность по отношению к другим читателям/писателям» (то есть инструкции чтения-изменения-записи без LOCK x86 являются только атомарными по отношению к прерываниям). Кроме того, нет ничего, что по своей сути предотвращает реализацию от отслеживания достоверности при более тонкой детализации * или *, предполагая, что потенциально устаревшие данные не будут изменены. Разумеется, такие мелкие моменты реализации * потенциала * не имеют существенного значения для ответа на вопрос (пока кто-то не решит фактически реализовать такие функции). –

+0

@ PaulA.Clayton, спасибо - добавил раздел. – Leeor