Потоковый атомарный класс: memory_order_seq_cst VS memory_order_relaxed

Я изучаю параллелизм, читая книгу Энтони Уильямса "Параллельность в C++ в действии". Это отличная книга. Мне трудно понять разницу между моделью памяти в атомарном классе. Например, memory_order_seq_cst против memory_order_relaxed, я надеюсь, что лучшее объяснение о них, если кто-то может. Ниже приведены коды из Листинга 5.5 в книге. Я добавил код для memory_order_seq_cst, чтобы проверить разницу с теми, которые с memory_order_relaxed. Но трудно увидеть разницу с выходом. Ни к объяснению в книге.

Спасибо л

#include <iostream>
#include <thread>
#include <atomic>

std:: atomic<int> x(0),y(0),z(0);
std:: atomic<bool> go(false);

unsigned const loop_count=10;

struct read_values
{
    int x,y,z;
};
read_values values1[loop_count];
read_values values2[loop_count];
read_values values3[loop_count];
read_values values4[loop_count];
read_values values5[loop_count];

void increment(std::atomic<int>* var_to_inc,read_values* values)
{
    while(!go)
        std::this_thread::yield();  // !!!!!
    for (unsigned i=0;i<loop_count;++i)
    {
//        values[i].x=x.load(std::memory_order_relaxed);
//        values[i].y=y.load(std::memory_order_relaxed);
//        values[i].z=z.load(std::memory_order_relaxed);
//        var_to_inc->store(i+1,std::memory_order_relaxed);
        values[i].x=x.load(std::memory_order_seq_cst);
        values[i].y=y.load(std::memory_order_seq_cst);
        values[i].z=z.load(std::memory_order_seq_cst);
        var_to_inc->store(i+1,std::memory_order_seq_cst);
        std::this_thread::yield(); // !!!!!
    }
}
void read_vals(read_values* values)
{
    while (!go)
        std:: this_thread::yield();
    for (unsigned i=0;i<loop_count;++i)
    {
//        values[i].x=x.load(std::memory_order_relaxed);
//        values[i].y=y.load(std::memory_order_relaxed);
//        values[i].z=z.load(std::memory_order_relaxed);
        values[i].x=x.load(std::memory_order_seq_cst);
        values[i].y=y.load(std::memory_order_seq_cst);
        values[i].z=z.load(std::memory_order_seq_cst);
        std::this_thread::yield(); // !!!!!
    }
}
void print(read_values* v)
{
    for (unsigned i=0;i<loop_count;++i)
    {
        if (i)
            std::cout<<",";
        std::cout<<"("<<v[i].x<<","<<v[i].y<<","<<v[i].z<<")";
    }
    std::cout<<std::endl;
}
int main(int argc, const char * argv[])
{
    std::thread t1(increment, &x,values1);
    std::thread t2(increment, &y,values2);
    std::thread t3(increment, &z,values3);
    std::thread t4(read_vals,values4);
    std::thread t5(read_vals,values5);
    go=true;
    t5.join();
    t4.join();
    t3.join();
    t2.join();
    t1.join();
    print(values1);
    print(values2);
    print(values3);
    print(values4);
    print(values5);
    return 0;
}

0 ответов

Другие вопросы по тегам