Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ pragma omp用于内部pragma omp主控或单个_C++_Openmp - Fatal编程技术网

C++ pragma omp用于内部pragma omp主控或单个

C++ pragma omp用于内部pragma omp主控或单个,c++,openmp,C++,Openmp,我正在处理一些东西,试图使孤立工作,并通过减少对#pragma omp parallel的调用来减少开销。 我尝试的是: #pragma omp parallel default(none) shared(mat,mat2,f,max_iter,tol,N,conv) private(diff,k) { #pragma omp master // I'm not against using #pragma omp single or whatever will work { while(diff

我正在处理一些东西,试图使孤立工作,并通过减少对
#pragma omp parallel
的调用来减少开销。 我尝试的是:

#pragma omp parallel default(none) shared(mat,mat2,f,max_iter,tol,N,conv) private(diff,k)
{
#pragma omp master // I'm not against using #pragma omp single or whatever will work
{
while(diff>tol) {
    do_work(mat,mat2,f,N);
    swap(mat,mat2);
    if( !(k%100) ) // Only test stop criteria every 100 iteration
         diff = conv[k] = do_more_work(mat,mat2);
    k++;
} // end while
} // end master
} // end parallel
void do_work(double *mat, double *mat2, double *f, int N)
{
int i,j;
double scale = 1/4.0;
#pragma omp for schedule(runtime) // Just so I can test different settings without having to recompile
for(i=0;i<N;i++)
    for(j=0;j<N;j++)
         mat[i*N+j] = scale*(mat2[(i+1)*N+j]+mat2[(i-1)*N+j] + ... + f[i*N+j]);
} 
do_work
取决于上一次迭代,因此while循环必须按顺序运行。 但我希望能够运行“do_work”并行程序,因此它看起来像:

#pragma omp parallel default(none) shared(mat,mat2,f,max_iter,tol,N,conv) private(diff,k)
{
#pragma omp master // I'm not against using #pragma omp single or whatever will work
{
while(diff>tol) {
    do_work(mat,mat2,f,N);
    swap(mat,mat2);
    if( !(k%100) ) // Only test stop criteria every 100 iteration
         diff = conv[k] = do_more_work(mat,mat2);
    k++;
} // end while
} // end master
} // end parallel
void do_work(double *mat, double *mat2, double *f, int N)
{
int i,j;
double scale = 1/4.0;
#pragma omp for schedule(runtime) // Just so I can test different settings without having to recompile
for(i=0;i<N;i++)
    for(j=0;j<N;j++)
         mat[i*N+j] = scale*(mat2[(i+1)*N+j]+mat2[(i-1)*N+j] + ... + f[i*N+j]);
} 
void do_工作(双*mat,双*mat2,双*f,int N)
{
int i,j;
双刻度=1/4.0;
#pragma omp for schedule(runtime)//这样我就可以测试不同的设置,而无需重新编译

对于(i=0;i原始代码中的外部并行区域仅包含一个串行段(
#pragma omp master
),这毫无意义,并有效地导致纯串行执行(无并行)。正如
do_work()
取决于上一次迭代,但要并行运行,必须使用同步。用于同步的openmp工具是(显式或隐式)同步障碍

例如(代码与您的类似):


效率应该更低,因为它会在每次迭代中创建一个新的线程团队,而不仅仅是同步。

这与在我的代码中只在“k++”之后放置一个屏障有很大不同吗?同样,您的示例中的屏障是必要的吗?在“pragma omp for‘?@anderschou 1)之后不存在隐含的屏障吗是的,它有很大的不同:在您的代码中,根本不存在并行性,因为并行区域只包含一个
区域,该区域仅由主线程执行(其中嵌套的并行性通常被忽略)2)是的,有一个隐含的障碍。因此,额外的障碍是多余的,编译器应该优化它。在任何情况下,至少留下一个关于隐含屏障的评论是有帮助的。(谢谢):D,这给了我所需要的答案。@ AndersSchou,请考虑我的回答。谢谢。