Барьер памяти на одноядерном ARM

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

Пока я не могу найти четкого объяснения, почему это не требуется на одноядерных процессорах. Предположим, что загрузка и хранилище переупорядочены в потоке A, и между обеими инструкциями происходит переключение контекста. В этом случае поток B может отреагировать не так, как ожидалось. Почему переключение контекста на одном ядре должно вести себя иначе, чем на двух потоках на разных ядрах? (кроме проблем с согласованностью кеша)

Например, информация с сайта ARM:

«Архитектурно определено, что программное обеспечение должно выполнять операцию барьера памяти данных (DMB): • между получением ресурса, например, посредством блокировки мьютекса (взаимное исключение) или уменьшения семафора, и любым доступом к этому ресурсу • перед выполнением ресурс, доступный, например, путем разблокировки мьютекса или увеличения семафора "

Это звучит очень ясно, однако в приведенном примере они явно относятся к многоядерной конфигурации.


person Waldorf    schedule 02.02.2015    source источник
comment
Где-то здесь, в Stackoverflow, также говорится, что барьеры памяти не требуются на одноядерных процессорах. В архитектурах есть разные подходы к упорядочиванию памяти: сильная или слабая. Так что это предложение может быть верным и для предыдущего.   -  person auselen    schedule 03.02.2015


Ответы (2)


Почему переключение контекста на одном ядре должно вести себя иначе, чем на двух потоках на разных ядрах? (кроме проблем с согласованностью кеша)

Потоки на отдельных ядрах могут действовать точно одновременно. У вас все еще есть проблемы с одним ядром.

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

Эта информация может быть вырвана из контекста (или не обеспечивает достаточного контекста).


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

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

Linux определяет еще несколько типов барьеров памяти,

  1. Написать / Сохранить.
  2. Зависимость от данных.
  3. Прочитать / Загрузить.
  4. Общие барьеры памяти.

В основном они довольно хорошо отображаются на DMB (DSB и IMB больше предназначены для модификации кода).

Более продвинутые процессоры ARM имеют несколько модулей загрузки / хранения. Теоретически некоторые переключатели не вытесняющих потоков Note1 (особенно с псевдонимами памяти) могут вызвать некоторые проблемы с многопоточным однопроцессорным приложением. Однако построить этот случай довольно сложно.

По большей части хороший порядок памяти обрабатывается ЦП с помощью инструкций планирования. Обычный случай, когда это имеет значение с одним процессором, - это когда программисты системного уровня изменяют CP15 регистры. Например, при включении MMU должно выдаваться ISB. То же самое может быть верно для определенных регистров оборудования / устройства. Наконец, загрузчику программ потребуются барьеры, а также операции с кешем даже в однопроцессорных системах.

UnixSmurf написал эти блоги о порядке доступа к памяти,

Это сложная тема, и вы должны конкретизировать типы обсуждаемых препятствий.

Примечание 1: я говорю без вытеснения, как если бы произошло прерывание, единственный ЦП, вероятно, обеспечит выполнение всех невыполненных запросов к памяти. С переключателем без вытеснения вы делаете что-то вроде longjmp для смены потоков. Теоретически вы можете изменить контексты до того, как все операции записи будут завершены. Системе потребуется только DMB в yield(), чтобы избежать этого.

person artless noise    schedule 02.02.2015
comment
Но предположим, что оптимизация выключена и компилятор не переупорядочивает. Итак, когда мы говорим только о переупорядочивании cpu. - person Waldorf; 02.02.2015
comment
Для одного процессора это почти невидимо. Я отредактировал некоторые случаи, когда это не так. - person artless noise; 02.02.2015

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

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

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

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

person user1751957    schedule 26.02.2015
comment
Да, это верно для регистров, но регистры могут храниться / находиться в ожидании во многих местах. Это неверно, если вещи кэшируются и имеют псевдонимы, например, два процесса с разными пространствами памяти. Я думаю, что было бы разумно поставить барьер памяти в любом переключателе контекста планировщика. Может это удастся сделать ненужным. Однако я не думаю, что вы можете сказать, что это не нужно во всех случаях (когда пространство памяти может нарушить логику кеширования)? Безусловно, это, вероятно, очень редко и может быть невозможно в некоторых системах. - person artless noise; 27.02.2015
comment
Однако даже в маловероятной ситуации, когда переупорядоченные инструкции все еще выполняются после переключения контекста, возможно, хранилища памяти, ЦП гарантирует, что это дает программному обеспечению видимость того, что инструкции выполняются в правильном порядке. - это дает такой вид только для сценария с одним потоком. Ни процессор, ни компилятор не заботятся о нескольких потоках, поэтому в конце концов существуют инструкции по ограждению. - person Groo; 21.03.2018