2015-08-07 5 views
2

Как известно, достаточно, чтобы использовать релиз-Acquire заказа (std::memory_order_acq_rel) когда мы используем только одну атомных переменные для хранения или загрузить его: https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.htmlДостаточно использовать std :: memory_order_acq_rel с одним атомным var для add/sub/inc/dec?

Но, это верно и для других элементарных ожидания свободных функций, таких как: сложение, вычитание, приращение и декремент?

ie next() функция потокобезопасна в следующем коде C++ для слабых (arm-cpu, ...) и сильных (x86-cpu, ...) моделей памяти или требуется другой барьерный порядок (ниже/выше)?

#include <iostream> 
#include <atomic> 
using namespace std; 

class progression_lf { 
public: 
progression_lf() : n(0) {} 

int next() { 
    // memory_order_acq_rel - enough, and increases performance for the weak memory models: arm, ... 
    int const current_n = n.fetch_add(1, std::memory_order_acq_rel); 
    int result = 2 + (current_n - 1)*3; 
    return result; 
} 

bool is_lock_free() { return ATOMIC_INT_LOCK_FREE; } 

private: 
std::atomic<int> n; 
}; 

int main() { 

    // reference (single thread) 
    for(int n = 0; n < 10; ++n) { 
     std::cout << (2+(n-1)*3) << ", "; 
    } 
    std::cout << std::endl; 

    // wait-free (multi-thread safety) 
    progression_lf p; 
    for(int n = 0; n < 10; ++n) { 
     std::cout << (p.next()) << ", "; 
    } 
    std::cout << std::endl; 

    std::cout << "lock-free & wait-free: " << 
     std::boolalpha << p.is_lock_free() << 
     std::endl; 

    return 0; 
} 

ответ

2

Боюсь, что вам не нужно какой-либо памяти C++ приказывать сильнее, чем расслабился здесь, если ваши темы не нуждаются больше, чем просто уникальный номер. Атомарность достаточно и std::memory_order_relaxed гарантирует, что:

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

Хотя на самом деле код с атомной операцией чтения-изменения-записи будет генерировать аппаратную инструкцию на x86, что подразумевает полный барьер памяти.

Вы можете видеть, какие разные компиляторы генерируют для разных платформ here.

+1

Большое спасибо, и особое спасибо за ссылку. – Alex