Parallel processing “什么是”呢;“隐式同步”;在OpenMP中

Parallel processing “什么是”呢;“隐式同步”;在OpenMP中,parallel-processing,synchronization,mpi,openmp,barrier,Parallel Processing,Synchronization,Mpi,Openmp,Barrier,OpenMP中的“隐式同步”到底是什么?您如何发现?我的老师说 #pragma omp parallel printf(“Hello 1\n”); 具有隐式同步。为什么?您是如何看待它的?同步是并行处理和openmp中的一个重要问题。一般来说,并行处理是异步的。您知道有几个线程正在处理一个问题,但您无法确切知道它们的实际状态、它们正在处理的迭代等。同步允许您控制线程执行 openmp中有两种同步:显式和隐式。显式同步通过允许创建屏障的特定openmp构造完成:#pragma omp屏障。屏障是

OpenMP中的“隐式同步”到底是什么?您如何发现?我的老师说

#pragma omp parallel
printf(“Hello 1\n”);

具有隐式同步。为什么?您是如何看待它的?

同步是并行处理和openmp中的一个重要问题。一般来说,并行处理是异步的。您知道有几个线程正在处理一个问题,但您无法确切知道它们的实际状态、它们正在处理的迭代等。同步允许您控制线程执行

openmp中有两种同步:显式和隐式。显式同步通过允许创建屏障的特定openmp构造完成:
#pragma omp屏障
。屏障是一种只能由所有线程同时通过的并行构造。所以在障碍之后,您确切地知道所有线程的状态,更重要的是,知道它们完成了多少工作

隐式同步在两种情况下完成:

  • 在平行区域的末端。Openmp依赖于fork-join模型。程序启动时,将创建一个单线程(主线程)。通过
    #pragma omp parallel
    创建并行节时,会创建多个线程(fork)。这些线程将同时工作,并行部分结束时将被销毁(join)。因此,在并行部分的末尾,您有一个同步,并且您精确地知道所有线程的状态(它们已经完成了它们的工作)。这就是您给出的示例中发生的情况。并行部分只包含
    printf()
    ,最后,程序等待所有线程的终止,然后继续

  • 在一些openmp构造(如
    #pragma omp for
    #pragma omp sections
    )的末尾,存在一个隐式屏障。只要所有螺纹未达到屏障,任何螺纹都不能继续工作。这对于准确了解不同线程所做的工作非常重要

例如,考虑下面的代码。

#pragma omp parallel
{
  #pragma omp for
  for(int i=0; i<N; i++)
    A[i]=f(i); // compute values for A
  #pragma omp for
  for(int j=0; j<N/2; j++)
    B[j]=A[j]+A[j+N/2];// use the previously computed vector A
} // end of parallel section
显然,这两个循环是完全独立的,如果正确计算
A
来启动第二个
for
循环,这并不重要。因此,同步对程序的正确性没有任何影响 添加同步屏障有两个主要缺点:

  • 如果函数
    f()
    的运行时间非常不同,则可能有一些线程已经完成了工作,而其他线程仍在计算。同步将迫使以前的线程等待,而这种空闲不会正确利用并行性

  • 同步是昂贵的。实现屏障的一种简单方法是在到达屏障时增加一个全局计数器,并等待计数器的值等于线程数
    omp\u get\u num\u threads()
    。为了避免线程之间的争用,必须使用需要大量周期的原子读-修改-写来增加全局计数器,而等待计数器的正确值通常使用浪费处理器周期的自旋锁来完成

  • 因此,存在抑制隐式同步的构造,对前一个循环编程的最佳方法是:

    #pragma omp parallel
    {
      #pragma omp for nowait  // nowait suppresses implicit synchronisations. 
      for(int i=0; i<N; i++)
        A[i]=f(i); // compute values for A
      #pragma omp for
      for(int j=0; j<N/2; j++)
        B[j]=g(j);// compute values for B
    } // end of parallel section
    
    #pragma omp并行
    {
    #nowait的pragma omp//nowait抑制隐式同步。
    对于(int i=0;i
    
    #pragma omp parallel
    {
      #pragma omp for nowait  // nowait suppresses implicit synchronisations. 
      for(int i=0; i<N; i++)
        A[i]=f(i); // compute values for A
      #pragma omp for
      for(int j=0; j<N/2; j++)
        B[j]=g(j);// compute values for B
    } // end of parallel section