Протокол MESI
Под загадочной аббревиатурой MESI, частенько встречающийся в отечественной и зарубежной литературе, скрывается ни что иное, как первые буквы четырех статусов кэш-линейки Modified Exclusive Shared Invalid (Модифицированная Девственная Скоммунизденая Инвалидная).
Но что каждый из этих статусов обозначает? Вот это мы сейчас и рассмотрим! Итак…
Статус "Modified" автоматически присваивается кэш-строкам при их модификации. Строка с таким атрибутом не может быть просто выброшена из кэша и при ее вытеснении обязательно должна выгружаться в кэш память более высокой иерархии или же основную память;
Статус "Exclusive" автоматически присваивается кэш-строкам при их загрузке из кэша более высокой иерархии или основной оперативной памяти. Модификация строки с атрибутом Exclusive влечет его автоматическую смену на атрибут Modified.
Строка с атрибутом Exclusive при ее вытеснении из кэша в зависимости от архитектурных особенностей системы либо просто уничтожается (inclusive - кэш), либо обменивается своим содержимым с одной из строк кэш-памяти более высокой иерархии (exclusive – кэш). см. так же. "Двухуровневая организация кэша"
Статус "Shared" присваивается кэш-строкам, потенциально присутствующим в кэш-памяти других процессоров (если это многопроцессорная система). Помимо этого, атрибут Shared указывает еще и на то, что строка когерентна содержимому соответствующих ей ячеек основной памяти. Поскольку, многопроцессорные системы далеко выходят за рамки нашего разговора, отложим этот вопрос до специального тома книги.
(Примечание: в AMD Athlon добавился новый статус "Owner" – "Владелец", и сам протокол стал записываться так: MOESI. Подробнее об этом будет так же рассказано в томе, посвященном многопроцессорным архитектурным).
Статус "Invalid" строка отсутствует в кэше и должна быть загружена из кэш памяти более высокой иерархии или же основной памяти.
Кэш данных первого уровня и кэш второго уровня Pentium- и AMD K6\Athlon процессоров поддерживает все четыре статуса, а кэш кода – только два из них Shared и Invalid. Остальные не поддерживаются по той простой причине, что кодовый кэш не допускает модификации своих линеек. А как же в этом случае работает самомодифицирующий код? – удивится иной читатель. А кто вам сказал, что он вообще работает? – возражу я. Независимо от того, присутствует ли модифицируемая ячейка в кодовом кэше или нет, инструкция записи не может непосредственно изменить ее содержимое, и она помещается в кэш первого (второго) уровня или основную оперативную память. Несмотря на то, что процессор все-таки отслеживает эти ситуации и обновляет соответствующие строки кодового кэша, самомодифицирующегося кода по возможности следует избегать, поскольку: во-первых, при обновлении строк гибнет вся преддекодированная информация, а, во-вторых, процессору приходится очищать конвейер и вновь начинать его заполнять сначала.
Причем, под самомодифицирующимся кодом в современных системах понимается не только истинно самомодифицирующийся код в его каноническом понимании, но и вообще всякая запись в область памяти, находящуюся в кодовом кэше. То есть, смесь кода и данных, которая так часто встречается в "ручных" ассемблерных программах, будет исполняться не скорее асфальтового катка, хотя формально она и не изменяет машинный код (но процессор-то об этом не знает!).
Статус |
Modified |
Exclusive |
Shared |
Invalid |
эта кэш линия действительна? |
да |
да |
да |
нет |
копия в памяти действительна? |
устарела |
действительна |
действительна |
этой строке вообще не соответствует никакая память |
содержится ли копия этой строки в других процессорах? |
нет |
нет |
может быть |
может быть |
запись в эту линию осуществляется… |
только в эту строку, без обращения к шине |
только в эту строку, без обращения к шине |
сквозной записью в память с аннулированием строки в кэшах остальных процессоров |
непосредственно через шину |