我想使用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
答案 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:如果与同步开销相比,迭代过于便宜,则可以让每个向量填充线程私有数组,然后在最后合并它们:
答案 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