首页 > 解决方案 > OpenMP 任意缩减(合并)

问题描述

我想使用 OpenMP 来收集一些数据。为此,我检查了许多候选人并仅收集满足某些条件的候选人。简化的示例如下。

#include <bits/stdc++.h>
#include "omp.h"

using namespace std;

class DataPoint {};

DataPoint random_data_point() {
    // generate random data point
}

bool test(DataPoint r) {
    // do something
}

int main() {
    constexpr int num_iterations = 10000;

    set<DataPoint> good_points;

#pragma omp parallel for reduction(???)
    for (int iter = 0; iter < num_iterations; iter++) {
        DataPoint r = random_data_point();
        if (test(DataPoint))
            good_points.insert(r);
    }

//  ...

    return 0;
}

问题是如何有效地使用 OpenMP。我的想法是每个线程收集自己的数据(在上面的示例中 - 它自己的集合),然后,在所有线程完成后,它们的集合被合并。

注 1:我的迭代非常独立(如上例所示),因此 OpenMP 应该会有所帮助。注2:在实际程序中,我使用了比set更复杂的数据结构。(实际上,它是数据点的凸包。)

标签: c++openmp

解决方案


现代 OpenMP 允许您定义自己的归约函数,因此如果您愿意,您应该能够以这种方式实现这一点,但实际上,对于如此简单的事情,仅按照这些行编写代码可能会更容易(未经测试,输入这个答案,未编译:-))

#pragma omp parallel
{
    set<Data_Point> thread_good_points;
#pragma omp for nowait
    for (int iter = 0; iter < num_iterations; iter++) {
        DataPoint r = random_data_point();
        if (test(DataPoint))
            thread_good_points.insert(r);
    }
#pragma omp critical
    good_points.merge(thread_good_points);
}

推荐阅读