我已经尝试了很长时间来学习如何并行化,并且我一直在阅读很多关于 OpenMP 的笔记。所以,我尝试使用它,我得到的结果是我尝试并行化的所有位置都比串行情况慢 5 倍,我想知道为什么......
我的代码是下一个:
toevaluate
是两列和两行长度的闪电矩阵。storecallj
并且storecallk
只是我用来存储调用并避免额外的函数调用的两个 blitz 向量。matrix
是一个长度为列(cols= rows)的方形犰狳矩阵,行的长度是行(我稍后会用它来做其他事情,将它定义为犰狳矩阵更方便)externfunction1
是一个在此之外定义的函数,它计算 f(a,b) 函数的 (x,y) 值,其中 (a,b) 是输入, (x,y) 是输出。Problem
是一个字符串变量并且normal
是一个布尔值。resultk
并且resultj
是这样的向量 (x,y) 存储这些函数的输出。externfunction2
是在此之外定义的另一个函数,它通过评估 funcci (i=1,2) 来计算双精度,这是一个闪电多项式。该多项式在双精度:innerprod 中进行评估以给出另一个双精度:wvaluei (i=1,2)。
我认为这些都是一般性的。代码如下。
{
omp_set_dynamic(0);
OMP_NUM_THREADS=4;
omp_set_num_threads(OMP_NUM_THREADS);
int chunk = int(floor(cols/OMP_NUM_THREADS));
#pragma omp parallel shared(matrix,storecallj,toevaluate,resultj,cols,rows, storecallk,atzero,innerprod,wvalue1,wvalue2,funcc1, funcc2,storediff,checking,problem,normal,chunk) private(tid,j,k)
{
tid = omp_get_thread_num();
if (tid == 0)
{
printf("Initializing parallel process...\n");
}
#pragma omp for collapse(2) schedule (dynamic, chunk) nowait
for(j=0; j<cols; ++j)
{
for(k=0; k<rows; ++k)
{
storecallj = toevaluate(j, All);
externfunction1(problem,normal,storecallj,resultj);
storecallk = toevaluate(k, All);
storediff = storecallj-storecallk;
if(k==j){
Matrix(j,k)=-atzero*sum(resultj*resultj);
}else{
innerprod =sqrt(sum(storediff* storediff));
checking=1.0-c* innerprod;
if(checking>0.0)
{
externfunction1(problem,normal, storecallk,resultk);
externfunction2(c, innerprod, funcc1, wvalue1);
externfunction2(c, innerprod, funcc2, wvalue2);
Matrix(j,k)=-wvalue2*sum(storediff*resultj)*sum(storediff*resultk)-wvalue1*sum(resultj*resultk);
}
}
}
}
}
}
而且速度很慢。我尝试过的另一件事是:
for(j=0; j<cols; ++j)
{
storecallj = toevaluate(j, All);
externfunction1(problem,normal,storecallj,resultj);
#pragma omp for collapse(2) schedule (dynamic, chunk) nowait
for(k=0; k<rows; ++k)
{
storecallk = toevaluate(k, All);
storediff = storecallj-storecallk;
...
我使用动态是为了避免出现问题,以防要评估的总点数不是 4 的倍数。
有人可以帮我理解为什么这么慢吗?