2013-03-19 3 views
17

Я понимаю, что DSB, DMB и ISB являются препятствиями для предотвращения переупорядочения инструкций. Я также могу найти много очень хороших объяснений для каждого из них, но довольно сложно представить, что я должен их использовать.Реальные варианты использования барьеров (DSB, DMB, ISB) в ARM

Кроме того, из открытых исходных кодов я вижу эти барьеры время от времени, но довольно сложно понять, почему они используются. Просто для примера, в Linux функции ядра 3,7 tcp_rcv_synsent_state_process, есть строка выглядит следующим образом:

if (unlikely(po->origdev)) 
      sll->sll_ifindex = orig_dev->ifindex; 
    else 
      sll->sll_ifindex = dev->ifindex; 

    smp_mb(); 

    if (po->tp_version <= TPACKET_V2) 
      __packet_set_status(po, h.raw, status); 

где smp_mb() в основном DMB. Не могли бы вы дать мне некоторые из ваших реальных примеров? Это поможет лучше понять барьеры.

+0

Этот вопрос был недавним примером: http://stackoverflow.com/q/15003405/1163019 – auselen

+0

В руководстве для программистов Cortex есть раздел для барьеров (11.2). http://infocenter.arm.com/help/topic/com.arm.doc.den0013c/index.html – auselen

+1

Я все еще голосую, чтобы закрыть, так как это очень широкий вопрос. – auselen

ответ

26

Извините, не собираюсь приводить пример, как вы спрашиваете, потому что, поскольку вы уже просматриваете исходный код Linux, у вас есть много таких, чтобы идти, и они не появляются Помогите. Никакой стыд в этом - каждый здравомыслящий человек, по крайней мере, сначала путается вопросами упорядочения доступа к памяти :)

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

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

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

Пол McKenney написал отличную статью о необходимости барьеров памяти, и какие эффекты они на самом деле имеют в процессоре: Memory Barriers: a Hardware View for Software Hackers

Если это немного слишком хардкор, я написал серию блога на 3-часть, которая немного более легкий, и заканчивается с ARM-специфическим представлением. Первая часть - Memory access ordering - an introduction.

Но если это конкретные списки примеров, которые вы используете, особенно для архитектуры ARM, вы можете сделать намного хуже, чем Barrier Litmus Tests and Cookbook.

экстра-экстра вид легкой программиста и не совсем архитектурно правильная версия:

  • DMB - всякий раз, когда доступ к памяти требует упорядочения в отношении другого доступа к памяти.
  • DSB - всякий раз, когда доступ к памяти должен быть завершен до выполнения программы.
  • ISB - каждый раз, когда выборки команд должны явно выполняться после определенной точки в программе, например, после обновления карты памяти или после написания кода, который должен быть выполнен. (На практике это означает «выбросить любые предварительно запрограммированные инструкции на данный момент».)
4

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

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

struct dma_control { 
    u32 owner; 
    void * data; 
    u32 len; 
}; 

Владелец, как правило, устанавливаются на что-то вроде OWNER_CPU или OWNER_HARDWARE, чтобы указать, кто из двух участников разрешено работать со структурой.

код, который изменяет это, как правило, нравится, как этот

dma->data = data; 
dma->len = length; 
smp_mb(); 
dma->owner = OWNER_HARDWARE; 

Итак, данные Len всегда ставим перед собственности получает переданы в аппаратных средствах DMA. В противном случае двигатель может получить устаревшие данные, такие как указатель или длина, которая не была обновлена, поскольку процессор переупорядочил доступ к памяти.

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

2

Один простой пример требования к барьеру - это спин-блокировка. Если вы реализуете спин-блокировку с использованием сравнения и замены (или LDREX/STREX на ARM) и без барьера, процессору разрешается спекулятивно загружать значения из памяти и лениво хранить рассчитанные значения в памяти, и ни один из них не требуется в порядке загрузки/хранения в потоке команд.

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

unixsmurf уже указал на это, но я также укажу вам на Barrier Litmus Tests and Cookbook. В нем есть несколько хороших примеров того, где и почему вы должны использовать барьеры.