Действительно ли барьеры памяти необходимы для совместно использованных неизменных данных атомарного подсчета ссылок?

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

Вот то, на что похож код выпуска:

void avocado_release(struct avocado *p)
{
    if (atomic_dec(p->refcount) == 0) {
        free(p->pit);
        free(p->juicy_innards);
        free(p);
    }
}

Делает atomic_dec нужен барьер памяти в нем? Если так, какой барьер памяти?

Дополнительные примечания: приложение должно работать на PowerPC и x86, таким образом, любая определенная для процессора информация одобрена. Я уже знаю об атомарном builtins GCC. Что касается неизменности, refcount является единственным полем, которое переключает продолжительность объекта.

12
задан Dietrich Epp 8 April 2010 в 10:57
поделиться

2 ответа

На x86 она превратится в инструкцию сборки с префиксом блокировки, например LOCK XADD .
Поскольку это одна инструкция, ее нельзя прерывать.В качестве дополнительной «возможности» префикс блокировки приводит к полному барьеру памяти:

«... заблокированные операции сериализуют все невыполненные операции загрузки и сохранения (то есть ждут их завершения)». ... "Заблокированные операции являются атомарными по отношению ко всем другим операциям с памятью и всем видимым извне событиям. Только выборка инструкций и доступ к таблице страниц могут передавать заблокированные инструкции. Заблокированные инструкции могут использоваться для синхронизации данных, записываемых одним процессором и считываемых другим процессором. . " - Руководство разработчика программного обеспечения для архитектур Intel® 64 и IA-32 , глава 8.1.2.

Барьер памяти фактически реализован как фиктивный LOCK OR или LOCK AND как в .NET , так и JAVA JIT ] на x86 / x64.
Итак, у вас есть полный забор на x86 в качестве дополнительного бонуса, нравится вам это или нет. :)

На КПП все по-другому. Пара LL / SC - lwarx & stwcx - с вычитанием внутри может использоваться для загрузки операнда памяти в регистр, вычитания единицы, а затем либо записи его обратно, если в целевом местоположении не было другого хранилища, или повторить весь цикл, если он был. LL / SC может быть прерван.
Это также не означает автоматический полный забор.
Однако это никоим образом не ставит под угрозу атомарность счетчика.
Это просто означает, что в случае x86 вы тоже получите ограждение «бесплатно».
В PPC можно вставить полное ограждение, выполнив команду (lw) sync .

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

11
ответ дан 2 December 2019 в 19:53
поделиться

Собираетесь ли вы реализовать свой собственный atomic_dec или вам просто интересно, будет ли функция, предоставляемая системой, вести себя как вы хотите?

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

2
ответ дан 2 December 2019 в 19:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: