OpenMP-将结果存储在矢量中

时间:2018-11-07 13:44:58

标签: c++ openmp

我想使用OpenPM将for循环与许多迭代并行化。结果应存储在向量中。

for (int i=0; i<n; i++)
{
    // not every iteration produces a result
    if (condition)
    {
        results.push_back (result_value);
    }
}

这不适用于#pragma omp parallel for

那么实现这一目标的最佳实践是什么?
是否有可能为每个线程使用单独的结果向量,然后在末尾组合所有结果向量?结果的顺序并不重要。

像这样的事情不可行,因为它会占用大量空间

int *results = new int[n];
for (int i=0; i<n; i++)
{
    // not every iteration produces a result
    if (condition)
    {
        results[i] = result_value;
    }
}

// remove all unused slots in results array

2 个答案:

答案 0 :(得分:3)

选项1:如果在将元素添加到向量之前每次迭代都花费大量时间,则可以将push_back保留在关键区域:

for (int i=0; i<n; i++)
{
    // not every iteration produces a result
    if (condition)
    {
#pragma omp critical
        results.push_back (result_value);
    }
}

如果线程主要忙于push_back以外的其他事务,那么关键区域的开销将很小。

选项2:如果与同步开销相比,迭代过于便宜,则可以让每个向量填充线程私有数组,然后在最后合并它们:

herehere有很好的副本。

答案 1 :(得分:1)

“天真”的方式: 您可以初始化多个向量(调用omp_get_max_threads()以了解当前并行区域内的线程数),然后调用并行区域内的omp_get_thread_num()以了解当前线程ID,并让每个线程写入其向量。 然后在平行区域之外将向量合并在一起。这是否值得,取决于将您的处理“繁重”与合并向量所需的时间进行比较。

如果知道向量的最大最终大小,则可以在处理之前保留它(这样push_back调用将不会调整向量的大小,并且可以节省处理时间),然后从关键部分(#pragma)中调用push_back方法omp关键),但是关键部分的运行速度非常慢,因此仅当您在循环内进行的处理非常耗时时才值得这样做。在您的情况下,“处理”似乎只是检查if子句,因此可能不值得。

最后,这是一个众所周知的问题。您应该阅读以下详细信息: C++ OpenMP Parallel For Loop - Alternatives to std::vector