【问题标题】:using #pragma omp parallel for make the program slower使用#pragma omp parallel 使程序变慢
【发布时间】:2015-02-08 20:05:15
【问题描述】:

我的 C++ 程序运行大约需要 300 秒。 在我的程序中,我需要 cwis 划分我的向量。 VS 分析器告诉这大约需要 15% 的运行时间。这是代码:

template <class T> myVector<T> cWisDivide(myVector<T> &vec1, 

myVector<T> &vec2)
{
    try
    {
        if (vec1._rows == vec2._rows)
        {
            myVector<T> result(vec1._rows);
            //#pragma omp parallel for 
            for (int r = 1; r <= vec1._rows; r++)
            {
                if (vec2(r) != 0)
                {
                    result(r) = vec1(r) / vec2(r);
                }
                else
                {
                    throw std::runtime_error("");
                }
            }
            return result;
        }
    }
    catch (const exception &e)
    {
        ....
    }
}

这个函数被调用了很多次。 如果我在循环之前使用#pragma ...,cpu 使用率会保持 100% 大约 350 秒。这比顺序运行程序所花费的时间要多。

如果有人能在这个问题上帮助我,我将不胜感激。

【问题讨论】:

  • vec1._rows 有多大?
  • r in for 循环应该在 for 之前定义。像这样:int r; #pragma.... for(r = 1...)
  • 尝试进一步向外计算平行区域。如果您多次调用这些函数,则每次调用时都要为初始化付费
  • @MichałWalenciak 嗯,不,对于将循环变量放在循环之外的并行意味着它的“最后一个”值必须由 omp 保留。这是一个额外的开销,会减慢它的速度。 (一点)。
  • @javad,你在 Windows 上对吗? Windows 上的 Taskman 说 25% 用于 4 核机器上的一个核心。这里真的很愚蠢的问题......你使用的是多核机器,不是吗?

标签: c++ openmp


【解决方案1】:

这可能会以多种方式出错:

  1. 在不知道 result 的类型的情况下,可能必须内置屏障以避免在修改它时出现竞争条件 - 您可以通过之后合并的并行结果向量来避免这种情况。
  2. vec1vec2 向量的复制开销可能大于性能奖励。

总而言之,这是一个关于可并行化向量类型的问题 - 请参阅您选择的 openMP 文档以了解有关可并行访问类型的更多信息。

【讨论】:

    【解决方案2】:

    不管怎样,我只是从 OMP 规范中查了一下...

    • 在循环区域内执行的 throw 必须导致在循环区域的同一迭代中恢复执行,并且引发异常的同一线程必须捕获它。

    我知道我不喜欢异常的外观。

    OpenMP API V4.0 第 59 页。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多