Parallel processing “什么是”呢;“隐式同步”;在OpenMP中
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屏障。屏障是
#pragma omp parallel
printf(“Hello 1\n”);
具有隐式同步。为什么?您是如何看待它的?同步是并行处理和openmp中的一个重要问题。一般来说,并行处理是异步的。您知道有几个线程正在处理一个问题,但您无法确切知道它们的实际状态、它们正在处理的迭代等。同步允许您控制线程执行 openmp中有两种同步:显式和隐式。显式同步通过允许创建屏障的特定openmp构造完成:
#pragma omp屏障
。屏障是一种只能由所有线程同时通过的并行构造。所以在障碍之后,您确切地知道所有线程的状态,更重要的是,知道它们完成了多少工作
隐式同步在两种情况下完成:
- 在平行区域的末端。Openmp依赖于fork-join模型。程序启动时,将创建一个单线程(主线程)。通过
创建并行节时,会创建多个线程(fork)。这些线程将同时工作,并行部分结束时将被销毁(join)。因此,在并行部分的末尾,您有一个同步,并且您精确地知道所有线程的状态(它们已经完成了它们的工作)。这就是您给出的示例中发生的情况。并行部分只包含#pragma omp parallel
,最后,程序等待所有线程的终止,然后继续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