Замедляют ли заборы памяти все ядра процессора?

Где-то когда-то я читал о заборах памяти (барьерах). Было сказано, что ограничение памяти вызывает синхронизацию кэша между несколькими ядрами процессора.

Итак, мои вопросы:

  1. Как ОС (или сам процессор) узнает, какие ядра нужно синхронизировать?

  2. Синхронизирует ли он кеш всех ядер процессора?

  3. Если ответом на (2) является «да» и предполагается, что операции синхронизации недешевы, замедляет ли использование заборов памяти ядра, которые не используются моим приложением? Например, если на моем 8-ядерном процессоре запущено однопоточное приложение, замедлит ли оно все остальные 7 ядер процессора, потому что некоторые строки кэша должны синхронизироваться со всеми этими ядрами?

  4. Являются ли приведенные выше вопросы совершенно неосведомленными, а заборы работают совершенно по-другому?

12

Решение

  1. ОС не нужно знать, и каждое ядро ​​процессора делает то, что ему говорят: каждое ядро ​​с ограничителем памяти должно выполнять определенные операции до или после, и это все. Ядро не синхронизируется «с» другими ядрами, оно синхронизирует доступ к памяти относительно себя.
  2. Забор в одном ядре не означает, что другие ядра синхронизируются с ним, поэтому обычно у вас будет два (или более) забора: один в устройстве записи и один в устройстве чтения. Забор, выполненный на одном сердечнике, не должен воздействовать на другие сердечники. Конечно, нет никаких гарантий по этому поводу в целом, только надежда, что здравомыслящие архитектуры не будут чрезмерно сериализовать многоядерное выполнение.
8

Другие решения

Как правило, память заборы используются для заказа местный операции. Возьмем, к примеру, этот псевдо-ассемблерный код:

load A
load B

Многие процессоры не гарантируют, что B действительно загружен после A, B может находиться в строке кэша, которая была загружена в кэш ранее из-за некоторой другой загрузки памяти. Если вы введете забор,

load A
readFence
load B

у вас есть гарантия, что B загружается из памяти после A. Если бы B был в кеше, но старше A, он был бы перезагружен.

Ситуация с магазинами такая же, наоборот. С

store A
store B

некоторые процессоры могут решить записать B в память до того, как они начнут записывать A. Опять же, для обеспечения порядка операций может потребоваться ограничение между этими двумя инструкциями. Необходимость ограничения памяти всегда зависит от архитектуры.


Как правило, вы используете ограждения памяти в парах:

  • Если один поток хочет опубликовать объект, он сначала создает объект, затем выполняет ограничение записи перед тем, как записать указатель на объект в общедоступное местоположение.

  • Поток, который хочет получить объект, читает указатель из общедоступной области памяти, затем он выполняет ограничение чтения, чтобы гарантировать, что все дальнейшие чтения, основанные на этом указателе, действительно дадут значения, предназначенные для потока публикации.

Если какой-либо забор отсутствует, читатель может прочитать значение одного или нескольких элементов данных объекта до его инициализации. Безумие наступает.

5

Если, скажем, восемь ядер, и каждое ядро ​​делает разные вещи, то эти ядра не будут обращаться к одной и той же памяти и не будут иметь одинаковую память в строке кэша.

Если ядро ​​№ 1 использует забор памяти, но никакое другое ядро ​​не обращается к памяти, к которой обращается ядро ​​№ 1, то другие ядра вообще не будут замедляться. Однако, если ядро ​​# 1 записывает в местоположение X, использует забор памяти, то ядро ​​# 2 пытается прочитать то же место X, забор памяти гарантирует, что ядро ​​# 2 выбрасывает значение местоположения X, если оно было в кэшировать и считывать данные из ОЗУ, получая те же данные, что записано ядром №1. Конечно, это требует времени, но именно для этого и существует память.

(Вместо чтения из оперативной памяти, если ядра разделяют некоторый кеш, данные будут считываться из кеша.)

1
По вопросам рекламы [email protected]