闪电战++;,犰狳和OpenMP非常慢

闪电战++;,犰狳和OpenMP非常慢,openmp,armadillo,blitz++,Openmp,Armadillo,Blitz++,我已经尝试了很长时间来学习如何并行化,并且我已经阅读了很多关于OpenMP的注释。所以,我尝试使用它,我得到的结果是,我尝试并行的所有位置都比串行情况慢5倍,我想知道为什么 我的代码是下一个: toevaluate是一个包含两列和两行长度的闪电矩阵 storecallj和storecallk只是我用来存储调用和避免额外函数调用的两个blitz向量 matrix是一个长度为列(cols=行)的方形犰狳矩阵,行的长度为行(我稍后将使用它来做其他事情,将其定义为犰狳矩阵更方便) externfunc

我已经尝试了很长时间来学习如何并行化,并且我已经阅读了很多关于OpenMP的注释。所以,我尝试使用它,我得到的结果是,我尝试并行的所有位置都比串行情况慢5倍,我想知道为什么

我的代码是下一个:

  • toevaluate
    是一个包含两列和两行长度的闪电矩阵
  • storecallj
    storecallk
    只是我用来存储调用和避免额外函数调用的两个blitz向量
  • matrix
    是一个长度为列(cols=行)的方形犰狳矩阵,行的长度为行(我稍后将使用它来做其他事情,将其定义为犰狳矩阵更方便)
  • externfunction1
    是一个在此之外定义的函数,它计算f(a,b)函数的(x,y)值,其中(a,b)是输入,(x,y)是输出
  • Problem
    是一个字符串变量,
    normal
    是一个布尔值
  • resultk
    resultj
    是存储此类函数输出的向量(x,y)
  • externfunction2
    是在此之外定义的另一个函数,它通过计算funci(i=1,2)来计算double,funci是一个blitz多项式。该多项式在double:innerprod中求值,得到另一个double:wvaluei(i=1,2)
我认为这些都是一般性的。代码如下

{
omp_集_动态(0);
OMP_NUM_线程数=4;
omp_设置_num_线程(omp_num_线程);
int chunk=int(floor(cols/OMP_NUM_线程));
#pragma omp并行共享(矩阵、storecallj、toevaluate、resultj、cols、行、storecallk、atzero、innerprod、wvalue1、wvalue2、func1、func2、storediff、检查、问题、正常、块)私有(tid、j、k)
{
tid=omp_get_thread_num();
如果(tid==0)
{
printf(“初始化并行进程…\n”);
}
#用于折叠(2)计划(动态、块)nowait的pragma omp

对于(j=0;jSorry,在我发布的第二部分中,它不包括“collapse(2)”,它只用于(j=0;j阅读代码,这是第一件要做的事情(除了检查用于测量这个5x结果的计时器)首先检查一个并行区域中修改的标量变量不应该是<代码>共享< /代码>。例如,在这里,<代码> StuleCaljJ应该是代码>私人< /代码>我相信……谢谢吉尔斯,对我来说。确定我在并行化和串行版本中使用timer.tic()和timer.toc()的时间正好在外部区域之外。storecallj是一个向量,但你是对的,它在每个线程内都被修改。如果我把它和privited中所有线程修改量放在一起,我会得到分段错误(内核转储)…另一方面,如果我将所有向量:storecallj、resultj、storecallk、storediff保持为共享,并对线程中更改的所有双精度变量:wvalue1、wvalue2进行私有化,检查程序运行情况,但仍然慢5倍。IDK what
timer.tic()
timer.toc()
do…对于定时OpenMP代码,建议使用
omp\u get\u wtime()
…现在,对于需要设置的各种临时变量
private
,只需在
并行
区域内而不是在外部声明它们。这样,它们将隐式地成为
private
,这正是您想要的,顺便说一句,这将使您的代码更具可读性。再次感谢@Gilles,我尝试过了这是:#pragma omp parallel shared(variables)private(tid,j,k){omp_set_dynamic(0);omp_NUM_THREADS=4;omp_set_NUM_THREADS(omp#u THREADS);数组resultj(2),resultk(2),storecallj(2),storecallk(2),storediff(2);双innerprod,wvalue1,wvalue2,checking;#pragma omp for schedule(dynamic,chunk),nowait for(…j…){storecallj=toevaluate(j,All);externfunction1(problem,normal,storecallj,resultj);for(…k…){使用omp_get_wtime()的时间仍然是一样的。我很难理解为什么速度慢。。。