Влияет ли переключатель процессов на сравнение и обмен std :: atomic в процессоре arm9? - PullRequest
0 голосов
/ 26 сентября 2018

Я новичок в std :: atomic в c ++ и пытаюсь понять реализацию операций сравнения и обмена под процессорами ARM. Я использую gcc на linux.

Когда я смотрю на код сборки

    mcr p15, 0, r0, c7, c10, 5
.L41:
    ldrexb  r3, [r2]
    cmp r3, r1
    bne .L42
    strexb  ip, r0, [r2]
    cmp ip, #0
    bne .L41
.L42:
    mcr p15, 0, r0, c7, c10, 5

Насколько я понимаю,

  1. для сравнения и обмена требуется несколько инструкций.
  2. ldrex помечает область памяти как эксклюзивную и считывает данные.
  3. strex хранит данные и очищает исключительный флаг для этого местоположения.

Мои вопросы

  1. действительно ли ldrex помечает Виртуальный адрес?как исключительный или физический адрес?

  2. Если Процесс P1 помечает виртуальный адрес как исключительный, и происходит переключение процесса на P2, будет ли этот виртуальный addr.быть доступным в P2?что произойдет, если P2 также выполнит ldrex по тому же адресу.

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

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

Моя функция c ++ выглядит как

std::atomic<bool> *flag;  
flag = (std::atomic<bool> *) (shm_ptr);  
bool temp = false ;  
while(!std::atomic_compare_exchange_strong((flag),&temp,true))  
{  
std::this_thread::yield();  
}  
// update shared memory  
std::atomic_store((flag), false);

1 Ответ

0 голосов
/ 26 сентября 2018

Да, безопасно использовать без блокировки std::atomic<T> в совместно используемой памяти, отображаемой различными процессами, во всех основных реализациях C ++ для ARM.

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


Прерывание до завершения strex приведет к сбою.Вам не нужно беспокоиться о том, чтобы код ядра изменил таблицы страниц между ldrex и strex.

Возобновление этого кода в середине после прерывания на том же или другом процессоре будет означать, что strex просто не удастся, потому чтоон не выполняется как часть «транзакции», запущенной ldrex.


. Атомарность не зависит от адреса в ARM и в любой обычной основной системе, которая реализует атомарность без блокировки в C ++ 11.

Все по-прежнему работает, если два потока / процесса на разных ядрах имеют одну и ту же физическую страницу, сопоставленную с разными виртуальными адресами.Стандарт C ++ 11 явно рекомендует, чтобы реализации работали таким образом без блокировок std::atomic<T>.(Он не требует этого, потому что тогда ему придется определить, что представляет собой процесс, и функции для переназначения виртуальной памяти.)

Это почти дубликат Без блокировкина практике атомные адреса без адреса? . См. цитаты из стандарта и более подробную информацию.


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

(Некоторые ранние процессоры, такие как ранние MIPS, иногда использовали виртуально адресованные кэши данных L1, но это не делается в системах, которые могут поддерживать несколько процессоров, AFAIK.)

...