Стандарт С++ 11 определяет модель памяти (1.7, 1.10), которая содержит порядки памяти, которые, грубо говоря, "последовательно последовательны", "приобретают", "потребляют", "освобождают" и "расслабляют", Точно так же программа правильна, только если она без гонок, что происходит, если все действия можно поместить в каком-то порядке, в котором происходит одно действие - до другого. Способ, которым выполняется действие X, - до действия Y заключается в том, что либо X секвенирован до Y (внутри одного потока), либо X межпоточно-происходит-до Y. Последнее условие дается, среди прочего, при
- X синхронизируется с Y или
- X упорядочен по закону до Y.
Синхронизация - происходит, когда X - это хранилище атомов с упорядочением "освобождения" на некоторой атомной переменной, а Y - атомная нагрузка с упорядочением "приобретать" для одной и той же переменной. Быть зависимым от заказа-раньше случается для аналогичной ситуации, когда Y - это загрузка с "потреблением" заказа (и подходящий доступ к памяти). Понятие синхронизирует-с расширяет транзитные отношения между событиями до того, как они упорядочиваются - друг перед другом в потоке, но при условии, что упорядоченное-зависимое расширение транзитивно распространяется только через строгий поднабор секвенированных-ранее называемых перенос-зависимостей, которые следует довольно большому набору правил и, в частности, может быть прерван с помощью std::kill_dependency
.
Итак, какова цель понятия "порядок зависимостей"? Какое преимущество оно обеспечивает в сравнении с более упорядоченным - до/синхронизация - с упорядочением? Поскольку правила для этого более строгие, я предполагаю, что их можно реализовать более эффективно.
Можете ли вы привести пример программы, в которой переход от выпуска/приобретения к выпуску/потреблению является правильным и обеспечивает нетривиальное преимущество? А когда std::kill_dependency
обеспечит улучшение? Высокоуровневые аргументы были бы хороши, но бонусные очки за аппаратные отличия.