从多个线程更新最大值 [英] Updating a maximum value from multiple threads

查看:85
本文介绍了从多个线程更新最大值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用原子操作从多个线程中更新最大值?

Is there a way to update a maximum from multiple threads using atomic operations?

说明性示例:

std::vector<float> coord_max(128);
#pragma omp parallel for
for (int i = 0; i < limit; ++i) {
    int j = get_coord(i); // can return any value in range [0,128)
    float x = compute_value(j, i);
    #pragma omp critical (coord_max_update)
    coord_max[j] = std::max(coord_max[j], x);
}

在上述情况下,关键部分使对整个向量的访问同步,而我们只需要对每个值的访问进行同步.

In the above case, the critical section synchronizes access to the entire vector, whereas we only need to synchronize access to each of the values independently.

推荐答案

在评论中提出建议之后,我发现了一个不需要锁定的解决方案,而是使用了std :: atomic/中的比较和交换功能.提升::原子的.我仅限于C ++ 03,因此在这种情况下,我将使用boost :: atomic.

Following a suggestion in a comment, I found a solution that does not require locking and instead uses the compare-and-exchange functionality found in std::atomic / boost::atomic. I am limited to C++03 so I would use boost::atomic in this case.

BOOST_STATIC_ASSERT(sizeof(int) == sizeof(float));
union FloatPun { float f; int i; };

std::vector< boost::atomic<int> > coord_max(128);
#pragma omp parallel for
for (int i = 0; i < limit; ++i) {
    int j = get_coord(i);
    FloatPun x, maxval;
    x.f = compute_value(j, i);

    maxval.i = coord_max[j].load(boost::memory_order_relaxed);
    do {
        if (maxval.f >= x.f) break;
    } while (!coord_max[j].compare_exchange_weak(maxval.i, x.i,
        boost::memory_order_relaxed));
}

将浮点值放入int中涉及一些样板,因为似乎原子浮点不是无锁的.对于内存顺序,我不是100%使用的,但是最低限度的放松"级别似乎还可以,因为不涉及非原子内存.

There is some boilerplate involved in putting float values in ints, since it seems that atomic floats are not lock-free. I am not 100% use about the memory order, but the least restrictive level 'relaxed' seems to be OK, since non-atomic memory is not involved.

这篇关于从多个线程更新最大值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆