Я реализую неблокирующий FIFO, используя связанный список.
Enqueue
ФИФО в основном:
void Enqueue(CNode node)
{
m_tail->m_next = node;
// Do I need a memory barrier here?
m_tail = node;
}
Мне интересно, есть ли необходимость добавлять барьер памяти, если он однопоточный (т. Е. Может ли компилятор / процессор изменить порядок двух строк выше?). А что, если он многопоточный (т. Е. Такой простой, как однократное чтение для одного записывающего устройства)?
редактировать: В соответствии с Вот, это случай анти-зависимость данных и заявления не должны быть переупорядочены. Поэтому я предполагаю, что процессор всегда должен обращаться к памяти в указанном порядке. Это правильно?
Компилятор не должен переставлять ваши назначения m_tail и m_tail-> next так, чтобы m_tail был назначен узлу до того, как был установлен m_tail-> next. Однако для многопоточного решения вам может понадобиться беспокоиться о:
temp = m_tail;
m_tail = node;
temp->next = node;
node->next = NULL;
При наличии барьера памяти компилятор и / или процессор должны завершить m_tail->next = node;
(а также node->next = NULL;
), прежде чем он пишет m_tail = node;
, Достаточно ли этого, чтобы гарантировать правильное выполнение, неясно, это зависит от того, что делает чтение кода на другом конце.
Других решений пока нет …