Префикс LOCK против протокола MESI?
Какова цель префикса x86 LOCK, если протокол MESI в любом случае не позволяет другим ядрам записывать данные, принадлежащие "эксклюзивному" владельцу?
Я немного запутался между тем, что предоставляет LOCK и что предоставляет MESI?
Я понимаю, что протокол MESI предназначен для обеспечения того, чтобы все ядра видели согласованное состояние памяти, но, насколько я понимаю, он также предотвращает запись ядер в память, в которую уже записывает другое ядро?
2 ответа
Протокол MESI делает кэши памяти эффективно невидимыми. Это означает, что многопоточным программам не нужно беспокоиться о том, что ядро читает устаревшие данные из них или два ядра записывают в разные части строки кэша и получают половину одной записи и половину другой, отправляемой в основную память.
Однако это не помогает при операциях чтения-изменения-записи, таких как увеличение, сравнение, свопинг и т. Д. Протокол MESI не будет останавливать два ядра, каждое из которых считывает один и тот же кусок памяти, каждое добавляет одно к нему, а затем каждое записывает одно и то же значение обратно, превращая два приращения в одно.
На современных процессорах префикс LOCK блокирует строку кэша, так что операция чтения-изменения-записи логически атомарна. Они упрощены, но, надеюсь, они дадут вам идею.
Разблокированный прирост:
- Получить строку кеша, поделился в порядке. Прочитайте значение.
- Добавьте один к прочитанному значению.
- Получите эксклюзивную строку кэша (если еще не E или M) и заблокируйте ее.
- Запишите новое значение в строку кэша.
- Измените строку кэша на измененную и разблокируйте ее.
Заблокированный прирост:
- Получите эксклюзивную строку кэша (если еще не E или M) и заблокируйте ее.
- Прочитайте значение.
- Добавьте один к этому.
- Запишите новое значение в строку кэша.
- Измените строку кэша на измененную и разблокируйте ее.
Заметили разницу? При разблокированном приращении строка кэша блокируется только во время операции записи в память, как и все записи. В заблокированном приращении строка кэша хранится по всей инструкции, от операции чтения до операции записи, в том числе и во время самого приращения.
Кроме того, у некоторых процессоров есть другие вещи, помимо кэшей памяти, которые могут повлиять на видимость памяти. Например, некоторые процессоры имеют предварительную выборку чтения или буфер записи, который может привести к тому, что операции с памятью будут выполняться не по порядку. При необходимости префикс LOCK (или эквивалентная функциональность на других процессорах) будет также делать все, что нужно для решения проблем с упорядочением операций с памятью.
Да, вы путаете две разные вещи. Протокол MESI - это протокол когерентности кэша, который гарантирует, что каждое ядро / процессор получает самые актуальные данные из кэша других процессоров (или памяти) по запросу. Если кешлайн находится в состоянии "E", это говорит запрашивающему процессору, что один (и только один) другой процессор имеет копию этой строки. Это все, что он делает; состояние "E" ни в коем случае не мешает запрашивающему процессору получить доступ к данным; он просто констатирует тот факт, что только один процессор имеет копию данных (и эта копия также соответствует той, что находится в памяти). Таким образом, если ядро запрашивает данные, находящиеся в состоянии "E", ядро получит их копию. Другая копия, которая была в "E", будет изменена в зависимости от того, запрашивает ли ядро копию для "записи" или "чтения". Если он запрашивается для записи, старая копия будет признана недействительной (состояние "I"), а если она предназначена для чтения, старая копия будет переведена в общее состояние "S".