Позволяет ли модель памяти C ++ 11 выводить расслабленные атомарные нагрузки из циклов?

Рассмотрим следующий код:

#include <atomic>

extern std::atomic<int> i;

void f(void)
{
while (!i.load(std::memory_order_relaxed))
;
}

Я ищу цитату из стандарта C ++ 11, в которой говорится, что компилятору не разрешено преобразовывать цикл в

  if (!i.load(std::memory_order_relaxed)) {
while (1)
;
}

Я видел некоторое обсуждение Вот но ничего неопровержимого.

редактироватьПредыдущая версия этого поста называлась внешней функцией внутри цикла.

Редактировать 2: Для мотивации: в книге «Эффективная Java» говорится, что виртуальная машина HotSpot выполняет следующее преобразование:

while (!done)
i++;

в

if (!done)
while (true)
i++;

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

11

Решение

Забудьте о расслабленном, нет гарантии, что атомный магазин Когда-либо стать видимым для атомной нагрузки в другом потоке. Лучшее, что вы получаете, это нормативное поощрение в [Atomics.order] / 12 (и аналогичная формулировка в [Intro.progress] / 18):

Реализации должны сделать атомные хранилища видимыми для атомных нагрузок
в разумные сроки.

…что не является обязательным требованием.

(C11 имеет идентичную формулировку в §7.11.3 / 16)

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

2

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector