Krz*_*ski 5 c++ multithreading atomic openmp
有没有办法使用原子操作从多个线程更新最大值?
说明性示例:
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);
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,临界区同步访问整个向量,而我们只需要独立地同步对每个值的访问.
根据评论中的建议,我找到了一个不需要锁定的解决方案,而是使用std :: atomic/boost :: atomic中的比较和交换功能.我仅限于C++ 03所以在这种情况下我会使用boost :: atomic.
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));
}
Run Code Online (Sandbox Code Playgroud)
将浮点值放入整数中有一些样板,因为看起来原子浮点数不是无锁的.我不是100%使用内存顺序,但限制最少的级别'放松'似乎没问题,因为不涉及非原子内存.
| 归档时间: |
|
| 查看次数: |
1611 次 |
| 最近记录: |