我是新手OpenMP
,我一直在尝试运行一个使用OpenMP添加两个数组的程序。在OpenMP教程中,我了解到,在for循环上使用OpenMP时,需要并行使用#pragma omp。但是我也使用#pragma omp parallel尝试了同样的事情,它也给了我正确的输出。以下是我要传达的代码片段。
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
和
#pragma omp parallel
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
两者有什么区别?
的
#pragma omp parallel
:
将创建一parallel region
组的threads
,其中每个线程将执行parallel region
封装的整个代码块。
从OpenMP 5.1可以阅读更正式的描述:
当线程遇到并行构造时,将创建一组线程以执行并行区域(..)。遇到并行构造的线程将成为新团队的主线程,在新并行区域的持续时间内线程数为零。新团队中的所有线程(包括主线程)都将执行区域。创建团队后,团队中的线程数在该并行区域的持续时间内保持不变。
该:
#pragma omp parallel for
将创建一个parallel region
(如前所述),并以threads
该区域的,它包围所述循环迭代将被分配,使用default chunk size
和default schedule
其是典型地 static
。但是请记住,default schedule
该OpenMP
标准的不同具体实现之间的差异可能会有所不同。
从OpenMP 5.1中,您可以阅读更正式的说明:
workharing-loop构造指定一个或多个关联循环的迭代将由团队中的线程在其隐式任务的上下文中并行执行。迭代分布在执行工作共享循环区域绑定到的并行区域的团队中已经存在的线程之间。
而且,
并行循环构造是一种用于指定并行构造的捷径,该并行构造包含具有一个或多个关联循环且没有其他语句的循环构造。
或者非正式地,#pragma omp parallel for
是构造函数#pragma omp parallel
与的组合#pragma omp for
。在您的情况下,这意味着:
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
在语义和逻辑上与以下内容相同:
#pragma omp parallel
{
#pragma omp for
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
TL; DR:在您的示例中,使用#pragma omp parallel for
循环将在线程之间并行化(即,循环迭代将在线程之间划分),而使用#pragma omp parallel
所有线程将执行(并行)所有循环迭代。
为了使其更具说明性,使用4
线程#pragma omp parallel
将导致类似以下内容:
而#pragma omp parallel for
与chunk_size=1
和静 schedule
会导致类似:
在代码方面,循环将被转换为类似于以下内容的逻辑:
for(int i=omp_get_thread_num(); i < n; i+=omp_get_num_threads())
{
c[i]=a[i]+b[i];
}
omp_get_thread_num例程返回当前线程组中调用线程的线程号。
返回当前团队中的线程数。在程序的顺序部分,omp_get_num_threads返回1。
或换句话说,for(int i = THREAD_ID; i < n; i += TOTAL_THREADS)
。用THREAD_ID
范围从0
到TOTAL_THREADS - 1
,并TOTAL_THREADS
表示在并行区域中创建的团队的线程的总数。
我了解到,在for循环上使用OpenMP时,需要并行使用#pragma omp。但是我也使用#pragma omp parallel尝试了同样的事情,它也给了我正确的输出。
它会为您提供相同的输出,因为在您的代码中:
c[i]=a[i]+b[i];
只读取arraya
和array b
,而arrayc[i]
是唯一要更新的数组,其值不取决于迭代i
将执行多少次。不过,#pragma omp parallel for
每个线程都会更新自己的i
,而每个线程都会更新#pragma omp parallel
相同i
的,因此会覆盖彼此的值。
现在尝试使用以下代码执行相同的操作:
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]= c[i] + a[i] + b[i];
}
}
和
#pragma omp for
{
for(int i=0;i<n;i++)
{
c[i] = c[i] + a[i] + b[i];
}
}
您将立即注意到差异。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句