2015-04-26 2 views
8

Какова цель префикса x86 LOCK, если протокол MESI запрещает другим ядрам записывать «эксклюзивные» данные в любом случае?LOCK prefix vs Протокол MESI?

Я немного запутался между тем, что предоставляет LOCK и что предлагает MESI?

Насколько я понимаю, протокол MESI позволяет гарантировать, что все ядра видят согласованное состояние памяти, но, как я понимаю, это также предотвращает запись сердечников в память, к которой уже написано другое ядро.

+2

Учитывайте разницу между заблокированным и разблокированным приращением: если два ядра одновременно увеличивают значение 0 в памяти, они оба решают записать 1 в память. Когерентность кеша не предотвращает потерю одного из обновлений. –

+0

@ KerrekSB извините, я не совсем понял, что вы имели в виду. Не будет ли кэширование когерентности гарантировать, чтобы только один из ядер владел кэшиной? Поэтому, если второе ядро ​​перешло к изменению кешины, в то время как первое увеличивалось, MESI предотвратил бы запись до тех пор, пока первое ядро ​​не завершило приращение? – user997112

+7

Инкремент - это не атомная операция. Сначала оба ядра считывают одно и то же значение (0) с чистой строки кэша. Затем они оба решают вычислить новое значение (1). Затем они оба записывают значение обратно. На этом этапе записи когерентность кэша не помогает, потому что запись в память не сразу влияет на согласованность (только чтение * с загрязненных страниц). –

ответ

-1

Да, вы смешиваете две разные вещи. Протокол MESI представляет собой протокол когерентности кэш-памяти, который гарантирует, что каждое ядро ​​/ процессор получает самые последние данные из кэша других процессоров (или памяти) по запросу. Если кешлайн находится в состоянии «E», это говорит запрашивающему процессору, что один (и только один) другой процессор имеет копию этой строки. Это все, что он делает; Состояние «E» в любом случае не позволяет запрашивающему процессору получить доступ к данным; в нем просто говорится о том, что только один процессор имеет копию данных (и эта копия также соответствует тому, что находится в памяти). Итак, если основной запрос данных, находящихся в состоянии «E», ядро ​​получит его копию. Другая копия, которая была в «E», будет изменена в зависимости от того, запрашивает ли ядро ​​копию для «записи» или «чтения». Если он запрашивается для записи, старая копия будет признана недействительной («Я»), и если она предназначена для чтения, то старая копия будет помещена в общее состояние «S».

+0

Вы неправильно используете функциональность префикса LOCK. Нет вреда для двух одновременных записей - с или без LOCK, вы увидите один из них, и это произвольно. –

+0

@DavidSchwartz Спасибо, Дэвид за комментарий, я удалил ту часть ответа. Кстати, мой комментарий о префиксе LOCK, который использовался при реализации взаимного исключения, был правильным. Кроме того, что более важно, порядок записи НЕ МОЖЕТ быть произвольным, как вы упомянули, и должен последовательно следовать модели памяти архитектуры; в противном случае память не будет согласованной (с точки зрения программы и программиста). – waleed

3

Протокол MESI делает тайники памяти невидимыми. Это означает, что многопоточные программы не должны беспокоиться о том, что ядро ​​считывает устаревшие данные из них или два ядра, записывая в разные части строки кэша, и получая половину одной записи и половину другой, отправленной в основную память.

Однако это не помогает при выполнении операций чтения-изменения-записи, таких как приращение, сравнение и свопинг и т. Д. Протокол MESI не останавливает два ядра от каждого чтения одного и того же блока памяти, каждый из которых добавляет к нему один, а затем каждый записывает одно и то же значение обратно, поворачивая два шага в один.

На современных процессорах префикс LOCK блокирует линию кэша так, что операция чтения-изменения-записи логически атомарна. Они упрощены, но, надеюсь, они дадут вам эту идею.

разблокирована шаг:

  1. Приобретать строки кэша, разделяемых прекрасно. Прочитайте значение.
  2. Добавьте один к считываемому значению.
  3. Приобретать кеш-строку эксклюзивно (если она еще не E или M) и заблокировать ее.
  4. Запишите новое значение в строку кэша.
  5. Измените строку кэша, чтобы изменить и разблокировать ее.

Locked прибавка:

  1. Приобретать строки кэша эксклюзивные (если он еще не E или M) и зафиксировать его.
  2. Прочитать стоимость.
  3. Добавьте один к нему.
  4. Запишите новое значение в строку кэша.
  5. Измените строку кэша, чтобы изменить и разблокировать ее.

Обратите внимание на разницу? В разблокированном приращении строка кэша блокируется только во время операции записи в память, как и все записи. В заблокированном приращении строка кэша сохраняется по всей команде, полностью от операции чтения до операции записи и включающей в себя сам приращение.

Кроме того, некоторые процессоры имеют вещи, отличные от кэшей памяти, которые могут повлиять на видимость памяти. Например, у некоторых ЦП есть считыватель prefetcher или размещенный буфер записи, который может привести к тому, что операции с памятью будут выполняться не в порядке. Там, где это необходимо, префикс LOCK (или эквивалентная функциональность на других ЦП) также будет выполнять все, что необходимо для управления проблемами порядка работы с памятью.

+0

«Протокол MESI не останавливает два ядра от каждого считывания одного и того же блока памяти ... превращая два приращения в один». Я смущен этим утверждением, поскольку это, кажется, противоречит тому, что пишет Пол МакКенни [в этой статье] (http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf). Например, переходы MESI (e) и (f) на странице 5 статьи вызваны операциями RMW. Более того, если два процессора пытаются одновременно аннулировать одну и ту же строку кэша, то, согласно статье, удастся помещать линию кэша в состояние M перед другим. –

+0

@ void-pointer Я не уверен, что сказать вам, кроме как прочитать мой ответ снова. Предположим, что два процессора делают прирост. Они оба читают, они оба увеличиваются, затем они оба пытаются писать. Как происходит тот факт, что одна запись будет происходить до другой, чтобы предотвратить потерянное приращение? Понятно, что нет. Вам нужно заблокировать строку кэша во время приращения, и это то, что делает префикс LOCK. Transition (e) - это операция чтения атома с атомом чтения-записи, и именно этот вопрос задается вопросом, почему мы нуждаемся. И ответ заключается в том, что упорядочить записи недостаточно. –

+0

Прошу прощения за глупые вопросы - я пытаюсь узнать больше о когерентности кеша. Насколько я понимаю, ЦП должен иметь строку кэша в состоянии M, чтобы изменить его, и точно один процессор может иметь заданную линию кэша в состоянии M за раз. Поэтому я не вижу, как оба ЦП могли одновременно увеличивать одну и ту же линию кэша. Если два процессора одновременно пытаются выполнить RMW, то (по моему мнению) один будет «выигрывать» и принуждать другого к недействительности своей копии строки кэша. Затем проигравший должен будет выдать недействительность для чтения, чтобы получить эксклюзивность перед выполнением RMW. –