2015-06-18 2 views
4

Robert Love говорит, что «set_task_state (задача, состояние) задает заданную задачу заданному состоянию. Если это применимо, это также обеспечивает барьер памяти для принудительного упорядочения на других процессорах (это необходимо на многопроцессорных системах) в противном случае это эквивалентно Задачи-> состояние = состояниеНазначение барьеров памяти в ядре linux

Мой вопрос: Как барьер памяти может заставить упорядоченность на других процессорах

что роберт любовь подразумевает под этим - Почему? это необходимо? Что это за заказ, о котором он может говорить? Говорит ли он о очередях планирования?

Если да, то у каждого процессора в SMP есть другая очередь планирования? Я смущен

+0

Чтобы ответить на другой вопрос - ** Да **, каждое ядро ​​ЦП в системе SMP имеет свой собственный ['runqueue'] (http://lxr.free-electrons.com/source/kernel/sched/sched .h # L538), на который он планирует задачи ... – TheCodeArtist

ответ

2

Ваш CPU, чтобы выжать дополнительную производительность, делает Out of Order Execution, который может выполнять операции в другом порядке, чем они указаны в коде. Оптимизирующий компилятор может изменить порядок операций, чтобы сделать код быстрее. Компилятор авторы/типы ядра должны заботиться, чтобы не изменить ожидания (или, по крайней мере, соответствовать спецификации, так что они могут сказать ваши ожидания не прав)

Вот пример

1: CPU1: task->state = someModifiedStuff 
2: CPU1: changed = 1; 
3: CPU2: if (changed) 
4: CPU2: ... 

Если Ждут» t есть барьер для установки состояния, которое мы могли бы изменить порядок 1 и 2. Поскольку ни одна из ссылок на другую однопоточную реализацию не увидит различий. Однако в ситуации SMP мы переупорядочиваем 1 и 2, строка 3 может видеть измененную, но не изменение состояния. Например, , если CPU1 выполнил строку 2 (но не 1), а затем CPU2 выполнил строки 3 и 4, CPU2 будет работать со старым состоянием, а если он будет очищен, изменение, которое только что сделал CPU1, потеряется.

Барьер сообщает системе, что в какой-то момент, между 1 и 2, он должен сделать вещи согласованными, прежде чем двигаться дальше.

Выполните поиск на «барьер памяти», вы найдете некоторые хорошие сообщения: Memory Barriers Are Like Source Control Operations

+0

Извинения за то, что вы так наивны. Я не понял, как «переупорядочить 1 и 2» вызовет проблему здесь? Поскольку каждый из них отличается - это не вызовет проблемы даже на SMP. – S22

+0

Я добавил редактирование, надеюсь, это поможет –

+0

В этом случае - весь код, который я пишу или в программе на C, необходимо выполнить последовательно. (Де-факто-барьер памяти). Но теперь вы говорите, что если мне нужно что-то, что нужно выполнить в другом процессоре SMP. Это может быть нить. Но все же я пытаюсь понять сценарии, в которых делается шаг за шагом. Это может произойти, даже если каждый исполняемый оператор является независимым. Не уверен: «Как ЦП» знает, что каждый из них независим или зависим. – S22

1

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

Во избежание переупорядочения из-за оптимизации компилятора достаточно ключевого слова volatile (говоря о C++ здесь). Таким образом, примитив синхронизации (например, lock) осуществляются как правильно используя volatile и какое-то ассемблер fence инструкции (есть многие из них, более или менее сильных: смотрите раздел 7.5.5 в http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html)

вы знаете, что замок есть?

x = 0; 

thread 1:       thread 2: 

a.lock();       a.lock(); 
x++;        x++; 
a.unlock();       a.unlock(); 

x приведет быть правильно 2. Теперь предположим, что нет гарантии в порядке выполнения инструкций этих двух потоков.Что делать, если выполняется инструкция есть (а и х независимы, так что испорченный выполнение будет разрешено, если lock() не был должным образом реализован с барьерами памяти):

x = 0; 

thread 1:       thread 2: 

x++;        x++; 
a.lock();       a.lock(); 
a.unlock();       a.unlock(); 

x может привести равна 2 или до 1.

Смежные вопросы