C 为什么我的OpenMP实现比单线程实现慢?

C 为什么我的OpenMP实现比单线程实现慢?,c,openmp,C,Openmp,我正在学习OpenMP并发,并尝试了一些现有的代码。在这段代码中,我试图使所有for循环并行。然而,这似乎使程序速度慢了很多,至少慢了10倍,甚至比单线程版本还要慢 代码如下: 我还使用了pthreads,它比单线程版本快 现在的问题是,我在OpenMP实现中犯了什么错误导致了这种减速 谢谢 编辑:单线程版本只是一个没有所有#pragmas的版本我认为您的代码太复杂了,无法在这里查看。我立即看到的一个错误是它甚至都不正确。在使用omp parallel for进行求和时,必须使用reduce(+

我正在学习OpenMP并发,并尝试了一些现有的代码。在这段代码中,我试图使所有for循环并行。然而,这似乎使程序速度慢了很多,至少慢了10倍,甚至比单线程版本还要慢

代码如下:

我还使用了pthreads,它比单线程版本快

现在的问题是,我在OpenMP实现中犯了什么错误导致了这种减速

谢谢


编辑:单线程版本只是一个没有所有#pragmas的版本

我认为您的代码太复杂了,无法在这里查看。我立即看到的一个错误是它甚至都不正确。在使用omp parallel for进行求和时,必须使用reduce(+:yourcountervariable)将不同线程的结果正确组合在一起。否则,一个线程可能会覆盖其他线程的结果。

至少有两个原因:

  • 您只需要对一个非常简单的循环进行8次迭代。您的运行时将完全由设置所有线程所涉及的开销控制

  • 在某些地方,
    临界
    部分会引起争用;所有线程都将尝试连续访问临界段,并相互阻塞


  • 我在代码中看到的一个问题是,在非常小的循环中使用OpenMP(例如,8或64次迭代)。由于管理费用的原因,这将是无效的。如果您想使用OpenMP解决n-queens问题,请查看OpenMP 3.0任务和线程并行性以解决分支和绑定问题。

    您是否在单核系统上运行它?除非您每个核使用的线程不超过1个,否则它们很可能会相互竞争共享资源。引入并行化并不会自动使程序运行得更快。@matt:也许你可以写一个答案来说明这一点,或者写一些解决方法的建议?谢谢代码中的pragma不正确且被忽略-但您应该理解OpenMP概念。我所说的pragma是“pragma omp end”。OpenMP杂注适用于C/C++中的结构化块,因此不需要结束杂注。只有在Fortran语言中,在没有表示块({})的情况下,才需要使用end指令。正确的子句是“reduction(+:yourcountvariable)”。如果不这样做,或者使用原子、关键或锁,您的结果甚至是不正确的。任务处理要求您以不同的方式看待并行化。然而,网上有几篇论文和演示文稿显示,当使用OpenMP任务并行处理nqueens问题时,几乎线性加速(2个线程的速度是串行线程的两倍,4个线程的速度几乎是串行线程的4倍,等等)。