Зачем нужен лимит порядка памяти на счетчике ссылок?

В примере boost::atomic функция unref:

void intrusive_ptr_release(const X * x)
{
  if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
    boost::atomic_thread_fence(boost::memory_order_acquire);
    delete x;
  }
}

1: операция fetch_sub ограничена memory_order_release, что предотвращает переупорядочивание предыдущих операций после точки. Но каковы возможные сцены, которые могли бы иметь такое явление?

2: в дополнение к memory_order_release при атомарной операции, почему перед удалением есть дополнительный memory_order_acquire?


person jiandingzhe    schedule 14.08.2014    source источник
comment
Попробуйте задать этот вопрос: stackoverflow.com/questions/16179938/   -  person firda    schedule 14.08.2014
comment
Этот кажется более связанным: общий счетчик ссылок указателя"> stackoverflow.com/questions/10268737/   -  person firda    schedule 14.08.2014
comment
sub — операция RMW.   -  person Kerrek SB    schedule 14.08.2014


Ответы (1)


Что касается первого вопроса, это предотвращает любое использование (*x) после fetch_sub (когда счетчик ссылок может быть равен 0, и поэтому использование запрещено). Возможными причинами являются переупорядочение ЦП или переупорядочение компилятора. Второй вопрос — это просто зеркало релиза; выпуск защищает магазины, а приобретение защищает грузы.

Может показаться, что refcount_fetch_sub(1, memory_order_acq_rel) тоже работает, но защищает только счетчик ссылок.

person MSalters    schedule 14.08.2014
comment
Я знаю, что и компилятор, и ЦП могут переупорядочивать команды. Однако в этом случае команда delete x зависит от результата команды fetch_sub. Почему все еще существует вероятность того, что вещи в delete x могут быть переупорядочены до fetch_sub? - person jiandingzhe; 21.08.2014
comment
В однопоточном представлении операции чтения могут быть переупорядочены перед несвязанной записью, т. е. другие элементы x уже могут быть прочитаны, чтобы предотвратить остановку конвейера в случае успешного выполнения ветви. А это, в свою очередь, может привести к удалению более старой версии x, когда другой поток обновил x. - person MSalters; 21.08.2014
comment
но это защищает только количество ссылок. Что вы имеете в виду? - person curiousguy; 27.11.2019