2017-01-31 1 views
1

Например, с несколькими потоками, исполняющих функцию обновления(): (. Я пытаюсь реализовать общую высокую оценку воды отдельных измерений в нескольких потоках)Используя атомную библиотеку C++, какой порядок (ы) памяти следует использовать для загрузки, а затем сравнить обмен?

// Statically allocated 
atomic<int> high_water{0}; 
//... 
void update(int meas) 
{ 
int i; 
bool replaced; 
do 
{ 
i = high_water.load(?); 
if (i >= meas) 
    break; 
replaced = high_water.compare_exchange_strong(i, meas, ?, ?); 
} 
while (!replaced); 
// ... 

ответ

1

compare_exchange_strong атомарные с в отношении high_water, независимо от того, какой порядок памяти вы ему указываете. Упорядочение памяти имеет значение только по отношению к другим операциям памяти. Это во многом зависит от того, как и когда другие потоки должны видеть high_water. Так как meas видна только в этой ветке, поэтому нет других загрузок и магазинов для рассмотрения. Таким образом, memory_order_relaxed верен.


В качестве вторичного ноты, compare_exchange_strong заменяет первый параметр с наблюдаемым значением, таким образом, что выполнение load является излишним.

int i = high_water.load(std::memory_order_relaxed); 
while (i < meas 
     && high_water.compare_exchange_strong(i, 
              meas, 
              std::memory_order_relaxed, 
              std::memory_order_relaxed 
              ) 
    ) 
    continue; 
+1

'while (i Potatoswatter

2

, что память порядка (s) следует использовать для нагрузки с последующим обменом сравнить?

Невозможно сказать, потому что вы не показываете код, где вызывается update(). Переупорядочение операций с памятью, связанных с этим вызовом, является реальной вещью на определенных платформах, если вы используете memory_order_relaxed (или что-то меньшее, чем значение по умолчанию). high_water может фактически использоваться для синхронизации данных между потоками. Если вы не беспокоитесь о тех возможных переупорядочениях, то std::memory_order_relaxed в порядке.

Как правило, для этих видов операций я бы не использовал более слабый порядок, чем по умолчанию (std::memory_order_seq_cst). Поскольку std::compare_exchange_strong является операцией Read-Modify-Write (RMW), которая по определению является дорогостоящей, поскольку она синхронизирует значение атома между ядрами, изменение порядка памяти не будет большим преимуществом. По крайней мере, на X86, с вашим кодом, компилятор выдает тот же самый объектный код для std::memory_order_seq_cst и std::memory_order_relaxed.

Боковое примечание, поскольку вы находитесь в цикле, вы можете использовать compare_exchange_weak(), что может привести к сбоям ложно, но это связано с циклом.