Получить / Выпустить VS Последовательная согласованность в C ++ 11 11 - PullRequest
0 голосов
/ 22 мая 2018
#include <thread>
#include <atomic>
#include <cassert>

std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};

void write_x()
{
    x.store(true, std::memory_order_release);
}

void write_y()
{
    y.store(true, std::memory_order_release);
}

void read_x_then_y()
{
    while (!x.load(std::memory_order_acquire))
        ;
    if (y.load(std::memory_order_acquire)) {
        ++z;
    }
}

void read_y_then_x()
{
    while (!y.load(std::memory_order_acquire))
        ;
    if (x.load(std::memory_order_acquire)) {
        ++z;
    }
}

int main()
{
    std::thread a(write_x);
    std::thread b(write_y);
    std::thread c(read_x_then_y);
    std::thread d(read_y_then_x);
    a.join(); b.join(); c.join(); d.join();
    assert(z.load() != 0);
}

Если я переназначу seq_cst для получения / выпуска в последнем примере cppreference , может ли assert(z.load() != 0) быть неудачным?

  • Seq_CST может предотвратить переупорядочение StoreLoad, но код этого не сделал.
  • Получение может предотвратить переупорядочение LoadLoad.
  • Выпуск может предотвратить переупорядочение StoreStore.

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Да, возможно, что z.load() == 0 в вашем коде, если вы используете порядок acquire / release, как вы сделали.Между независимыми записями в x и y не существует отношений «до и после».Это не случайное совпадение, которое использовалось в этом примере специально для иллюстрации случая, когда приобретение / освобождение недостаточно.

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

Я не знаю, допускают ли какие-либо общие процессоры общего пользованияIRIW меняет порядок, когда используются барьеры и / или инструкции, необходимые для приобретения и выпуска, но я не удивлюсь, если некоторые из них сделают.

0 голосов
/ 22 мая 2018

Основное свойство, которое не гарантировано приобретением / выпуском, представляет собой единый общий порядок изменений.Это гарантирует, что c и d наблюдают (несуществующие) предыдущие действия a и b, если они видят true от нагрузок.

Очевидный пример этого - система с несколькими процессорами (физические сокеты).В матрице 1 установлена ​​резьба сердечника А a и резьба сердечника С c.Плашка 2 имеет резьбу сердечника B b и резьбу сердечника D d.Межсоединение между двумя сокетами имеет большую задержку по сравнению с операцией памяти, которая затрагивает встроенный кэш.

a и b выполняются в одно и то же время настенных часов.C находится в состоянии готовности с A, поэтому можно сразу увидеть хранилище до x, но межсоединение задерживает его наблюдение за хранилищем до y, поэтому оно видит старое значение.Точно так же D находится на кристалле с B, поэтому он видит хранилище до y, но пропускает хранилище до x.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...