предисловие
В процессоре с несколькими ядрами каждое ядро имеет свой собственный кеш, и как обеспечить согласованность содержимого кеша нескольких ядер — проблема, с которой легко столкнуться.Протокол MESI — это специальный протокол A для решения согласованности кеша. Многие процессоры используют протокол MESI или вариант протокола MESI, а протокол MESI на самом деле является вариантом протокола MSI. Протокол MESI использует стратегию обратной записи для обновления кэша, что еще больше повышает его производительность, но также несет дополнительные риски.Проблем, вызванных обратной записью, можно избежать, используя барьеры памяти при написании программ.
Введение в протокол MESI
Происхождение названия протокола MESI состоит из четырех описанных им состояний кэша, а именно M (модифицированный), E (монопольный), S (общий) и I (недействительный). Описание каждого состояния выглядит следующим образом:
государство | описывать |
---|---|
Modified | Содержимое текущего кеша допустимо, данные были изменены и не согласуются с данными в памяти, данные существуют только в текущем кеше |
Exclusive | Содержимое текущего кеша допустимо, данные согласуются с данными в памяти, и данные существуют только в текущем кеше. |
Shared | Содержимое текущего кеша допустимо, данные согласуются с данными в памяти, и данные существуют в нескольких кешах. |
Invalid | Текущий кеш недействителен |
переход состояния
Протокол МЭСИ фактически является конечным автоматом, состояние кеша будет передаваться в зависимости от воздействия внешних событий, а конкретные события делятся на две категории: запрос процессора к кешу и запрос шины к кешу:
- PrRd: процессор запросил чтение блока кэша.
- PrWr: процессор запросил запись блока кеша
- BusRd: запрос Snooper указывает, что другой процессор запросил чтение блока кэша.
- BusRdX: запрос отслеживания указывает, что другой процессор запросил запись в блок кэша, которым процессор не владеет.
- BusUpgr: запрос отслеживания указывает, что другой процессор запросил запись блока кэша, принадлежащего этому процессору.
- Flush: запрос Snooper указывает, что запрос состоит в том, чтобы записать весь кеш обратно в основную память.
- FlushOpt: запрос отслеживания, чтобы указать, что весь блок кэша отправляется на шину для отправки другому процессору (копия из кэша в кэш)
Переход между состояниями происходит следующим образом:
начальное состояние | действовать | отклик |
---|---|---|
Invalid(I) | PrRd |
|
PrWr |
|
|
Exclusive(E) | PrRd |
|
PrWr |
|
|
Shared(S) | PrRd |
|
PrWr |
|
|
Modified(M) | PrRd |
|
PrWr |
|
начальное состояние | действовать | отклик |
---|---|---|
Invalid(I) | BusRd |
|
BusRdX/BusUpgr |
|
|
Exclusive(E) | BusRd |
|
BusRdX |
|
|
Shared(S) | BusRd |
|
BusRdX |
|
|
Modified(M) | BusRd |
|
BusRdX |
|
Введение барьеров памяти
Конструкция МЭСИ относительно проста и понятна, но есть два места, которые приведут к падению производительности: во-первых, при обновлении кэша в недействительном состоянии необходимо попытаться получить самые свежие данные из других ЦП или даже из памяти; во-вторых, необходимо сделать кэш недействительным. Дождитесь подтверждения от других ЦП; эти две операции занимают много времени, и если ЦП будет продолжать ждать во время этих двух процессов, это будет пустой тратой времени.
store buffer
Чтобы уменьшить задержку записи в кэш в недействительном состоянии, можно ввести буфер сохранения. Поскольку операция записи произойдет в любом случае, ЦП сначала отправит сигнал, чтобы уведомить другие ЦП о сбое кеша, а затем обновит эту операцию записи в буфер сохранения и подождет, пока другие ЦП подтвердят получение сигнала перед отправкой. результат записываю в память.
Это позволяет избежать трудоемкого ожидания подтверждения другим процессором при обновлении кеша, но также приводит к тому, что обновление процессора не записывается в кеш вовремя, поэтому, когда процессору необходимо прочитать кеш, ему необходимо подтвердить, есть ли есть ли необходимость в хранении буфера данных, этот механизм называется переадресацией хранилища. Стоит отметить, что когда ЦП читает и записывает собственный буфер хранилища, соответствующие изменения данных не воспринимаются другими ЦП.
invalidate queue
Когда ЦП получает сообщение об аннулировании кеша, ожидается, что ЦП немедленно выполнит аннулирование. Но на самом деле, процессор не сразу выполняет операцию инвалидации, а сначала отправляет сообщение для подтверждения получения, а затем добавляет операцию инвалидации в очередь инвалидации, и операция в очереди затем будет выполнена в соответствующее время ( не обязательно сразу). Причина, по которой необходима очередь аннулирования, также заключается в том, что операция аннулирования является дорогостоящей, и ЦП должен отбросить кеш, чтобы выполнить операцию аннулирования, что приводит к снижению частоты попаданий в кэш. Преимущество этого в том, что это может повысить производительность ЦП, но также приводит к возможности просроченных данных в кэше.
барьер памяти
Для проблем, вызванных двумя оптимизациями буфера хранения и очереди аннулирования, мы также предоставляем барьеры памяти в качестве решения. Барьер памяти передается тому, кто написал программу, и его можно использовать для обхода упомянутых выше проблем.
Барьеры памяти делятся на барьеры записи и барьеры чтения.При написании программ вы можете добавлять барьеры памяти там, где это необходимо. Барьер записи заставит процессор очистить содержимое буфера хранения, то есть все изменения будут записаны в кеш, а затем изменения будут записаны в память, делая ее видимой для других процессоров; барьер чтения будет заставить ЦП выполнять все недействительные в операции очереди недействительных, чтобы сделать недействительным содержимое собственного кэша, чтобы ЦП получал последние данные кэша из памяти или другого ЦП.
разное
На первый взгляд, протокол MESI чем-то похож на модель памяти и ключевое слово volatile в java, и позже он будет подробно раскрыт.