c ++ 11 — C ++ memory_order_consume, kill_dependency, зависимость упорядочена-до, синхронизируется-с

я читаю C ++ Параллелизм в действии Энтони Уильямс. В настоящее время я нахожусь в точке, где он описывает memory_order_consume.

После этого блока есть:

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

Это немного пугает меня, потому что я не совсем понимаю несколько вещей:


Чем зависимость-заказ-до отличается от синхронизации-с? Они оба создают отношения до и после. Какая точная разница?


Я запутался в следующем примере:

int global_data[]={ … };
std::atomic<int> index;
void f()
{
int i=index.load(std::memory_order_consume);
do_something_with(global_data[std::kill_dependency(i)]);
}

Что именно делает kill_dependency? Какую зависимость это убивает? Между какими сущностями? И как компилятор может использовать это знание?


Можно ли безопасно заменить все значения memory_order_consume на memory_order_acquire? То есть это строже во всех смыслах?


В листинге 5.9 можно безопасно заменить

std::atomic<int> data[5]; // all accesses are relaxed

с

int data[5]

? То есть можно ли использовать и получать информацию для синхронизации доступа к неатомарным данным?


Он описывает расслабленный, приобретенный и выпущенный на некоторых примерах с людьми в кабинах. Есть ли похожие простые описания seq_cst и потребления?

4

Решение

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

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

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

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

Порядок памяти адресов только номер 3. Атомарные функции адреса 1 и 2, и, в зависимости от аргумента порядка памяти, может быть также 3. Таким образом, memory_order_relaxed означает «не беспокойтесь о цифре 3. Код по-прежнему обрабатывает 1 и 2. В этом случае вы должны будете использовать и освободить, чтобы обеспечить правильное упорядочение памяти.

5

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

Чем зависимость-заказ-до отличается от синхронизации-с?

От 1.10 / 10: «[Примечание: отношение« упорядочено по зависимости раньше »аналогично« синхронизируется с », но использует освобождение / потребление вместо выпуска / приобретения. — примечание конца]».

Что именно делает kill_dependency?

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

Можно ли безопасно заменить все значения memory_order_consume на
memory_order_acquire? То есть это строже во всех смыслах?

Я так думаю, но я не уверен.

2

memory_order_consume требует, чтобы элементарная операция выполнялась до всех неатомарных операций, которые зависят от данных. Зависимость данных — это любая зависимость, в которой вы не можете оценить выражение без использования этих данных. Например, в x-> y нет способа оценить x-> y без предварительной оценки x.

kill_dependency — уникальная функция. Все остальные функции имеют зависимость данных от своих аргументов. Kill_dependency явно не делает. Он появляется, когда вы знаете, что сами данные уже синхронизированы, но выражение, которое вам нужно получить, может не синхронизироваться. В вашем примере do_something_with может предполагать, что любое кэшированное значение globalldata [i] безопасно для использования, но само i должно фактически быть правильным атомарным значением.

memory_order_acquire строго сильнее если все изменения в данных правильно высвобождаются с соответствующим memory_order_release.

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