Parallel processing OpenMP并行化循环

Parallel processing OpenMP并行化循环,parallel-processing,openmp,sections,Parallel Processing,Openmp,Sections,我想把这种循环并行化。请注意,每个“calc_块”都使用在上一次迭代中获得的数据 for (i=0 ; i<MAX_ITER; i++){ norma1 = calc_block1(); norma2 = calc_block2(); norma3 = calc_block3(); norma4 = calc_block4(); norma = norma1+norma2+norma3+norma4; ...some calc...

我想把这种循环并行化。请注意,每个“calc_块”都使用在上一次迭代中获得的数据

for (i=0 ; i<MAX_ITER; i++){

    norma1 = calc_block1();
    norma2 = calc_block2();
    norma3 = calc_block3();
    norma4 = calc_block4();

    norma = norma1+norma2+norma3+norma4;
    ...some calc...
    if(norma<eps)break;
}

for(i=0;i您可以通过在并行区域内移动整个循环来减少开销。因此,用于实现团队的池中的线程只会“唤醒”一次。这有点棘手,需要仔细考虑变量共享类:

#pragma omp并行专用(i,…)num_线程(4)
{
对于(i=0;i
单个
构造的末端都有隐式屏障,因此线程将在进入下一个循环迭代之前进行同步。
单个
构造复制程序先前的序列部分。
private
子句中的
..
部分应列为many作为仅与
…某些计算…
相关的可能变量。其思想是使用线程本地变量运行串行部分,因为大多数OpenMP实现对共享变量的访问速度较慢


请注意,由于完全不同的原因,通常时间加速可能不是线性的。例如
calc_blockX()
(其中
X
1
2
3
4
)可能计算强度太低,因此需要很高的内存带宽。如果内存子系统不能同时为所有4个线程提供数据,则速度将小于4。例如-。

最大值是多少?整个代码和每个块的绝对时间成本分别是多少y?我有点搞不懂你为什么使用
flush
。据我所知,single
有一个隐式屏障,在退出时调用隐式
flush
,所有共享对象都是同步的,应该包括
norma
。我从未使用过
flush
,所以这是我想了解的。@redrum,你是我提出了一个有效的论点,反对使用
flush
。根据IBM(和其他公司)的隐式flush,“除了自动存储持续时间无法访问的对象外,所有共享对象都是同步的。”这句话的最后一部分“除了自动存储持续时间无法访问的对象外”是什么意思是什么意思?这让我有点紧张。我不知道。OpenMP规范中没有这种语言。“自动存储持续时间”通常转换为“本地堆栈变量”,这可能意味着在函数中调用的刷新只同步来自可见(可访问)主线程的共享堆栈变量子集在调用的函数中,
flush
仅在实践中与
原子的
或其他手动同步原语(即非
障碍
,显式或非显式)结合使用时才有用。这确实很棘手。以我的经验,例如,GCC总是使用指针访问共享变量(即,它不实现放松记忆模型)和
flush
指令被简单地转换为一条
MFENCE
指令,该指令将刷新前面所有无序的获取和存储。在其他实现中
flush
可能充当
volatile
指令编译器生成实际内存存储,其中代码经过寄存器优化。
for (i=0 ; i<MAX_ITER; i++){
  #pragma omp parallel sections{
     #pragma omp section
       norma1 = calc_block1();
     #pragma omp section
       norma2 = calc_block2();
     #pragma omp section
       norma3 = calc_block3();
     #pragma omp section
       norma4 = calc_block4();
  }

  norma = norma1+norma2+norma3+norma4;
    ...some calc...
  if(norma<eps)break;
}