Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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 parallel和#pragma omp parallel之间的差异_C++_C_Multithreading_Parallel Processing_Openmp - Fatal编程技术网

C++ #pragma omp parallel和#pragma omp parallel之间的差异

C++ #pragma omp parallel和#pragma omp parallel之间的差异,c++,c,multithreading,parallel-processing,openmp,C++,C,Multithreading,Parallel Processing,Openmp,我不熟悉OpenMP,我一直在尝试运行一个程序,使用OpenMP添加两个阵列。在OpenMP教程中,我了解到在for循环中使用OpenMP时,我们需要使用#pragma omp parallel for。但我也尝试过同样的方法,使用#pragma omp parallel,它也给出了正确的输出。下面是我试图传达的代码片段 #pragma omp parallel for { for(int i=0;i<n;i++) { c[i]=a[i

我不熟悉
OpenMP
,我一直在尝试运行一个程序,使用OpenMP添加两个阵列。在OpenMP教程中,我了解到在for循环中使用OpenMP时,我们需要使用#pragma omp parallel for。但我也尝试过同样的方法,使用#pragma omp parallel,它也给出了正确的输出。下面是我试图传达的代码片段

#pragma omp parallel for
{
      for(int i=0;i<n;i++)
       {  
            c[i]=a[i]+b[i];
       }
}
#pragma omp parallel for
{
对于(inti=0;i

#pragma omp parallel

将创建一个
并行区域
,其中包含一组
线程
,每个线程将执行
并行区域
包含的整个代码块

从中可以看到更正式的描述:

当一个线程遇到一个并行构造时,一个线程组被激活 创建以执行并行区域(..) 遇到并行构造的线程成为主线程 新团队的线程,在持续时间内线程数为零 新平行区域的所有线程。新团队中的所有线程,包括 主线程,执行区域。创建团队后 团队中的线程数在任务期间保持不变 平行区域

委员会:

#pragma omp parallel for

将创建一个
平行区域
(如上所述),并且将使用
默认块大小
默认调度
(通常为
静态
)为该区域的
线程
)分配它所包含的循环的迭代。但是,请记住,
默认调度
可能在该区域的不同具体实现中有所不同
OpenMP
标准

从中,您可以阅读更正式的描述:

工作共享循环构造指定一个或多个循环的迭代 中的线程将并行执行更多关联的循环 团队在其隐含任务的上下文中。迭代是 分布在已存在于 执行工作共享循环区域所指向的并行区域 绑定

,

并行循环构造是指定并行循环的快捷方式 包含具有一个或多个关联的循环构造的构造 循环,没有其他语句

或者非正式地说,
#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];
       }
}
在哪里

omp_get_thread_num例程返回 调用线程的当前团队

返回当前团队中的线程数。按顺序 程序的omp_get_num_threads部分返回1

或者换句话说,
用于(inti=THREAD\u ID;i
。其中
THREAD\u ID
范围从
0
TOTAL\u THREADS-1
,并且
TOTAL\u THREADS
表示在并行区域上创建的团队的线程总数

我了解到我们需要暂时使用#pragma omp parallel 在for循环上使用OpenMP。但我也尝试过同样的方法 使用#pragma omp parallel,它还为我提供了正确的输出。

它提供相同的输出,因为在代码中:

 c[i]=a[i]+b[i];
数组
a
和数组
b
仅被读取,而数组
c[i]
是唯一被更新的线程,其值不取决于迭代
i
的执行次数。然而,使用
#pragma omp parallel for
时,每个线程将更新自己的
i
,而使用
#pragma omp parallel
时,线程将更新相同的
i
s,因此超过相互认同价值观

现在尝试对以下代码执行相同的操作:

#pragma omp parallel for
{
      for(int i=0;i<n;i++)
       {  
            c[i]= c[i] + a[i] + b[i];
       }
}
#pragma omp parallel for
{
对于(inti=0;i

#pragma omp parallel

将创建一个
并行区域
,其中包含一组
线程
,每个线程将执行
并行区域
包含的整个代码块

从中可以看到更正式的描述:

当一个线程遇到一个并行构造时,一个线程组被激活 创建以执行并行区域(..) 遇到并行构造的线程成为主线程 新团队的线程,在持续时间内线程数为零 新平行区域的所有线程。新团队中的所有线程,包括 主线程,执行区域。创建团队后 团队中的线程数在任务期间保持不变 平行区域

委员会:

#pragma omp parallel for

将创建一个
平行区域
(如上所述),并且将使用
默认块大小
默认调度
(通常为
静态
)为该区域的
线程
)分配它所包含的循环的迭代。但是,请记住,
默认调度
可能在该区域的不同具体实现中有所不同
OpenMP
标准

从中,您可以阅读更正式的描述:

工作共享循环构造指定一个或多个循环的迭代 中的线程将并行执行更多关联的循环 团队在其隐含任务的上下文中。迭代是 分布在已存在于 执行工作共享循环区域所指向的并行区域 绑定

,

并行循环构造是指定并行循环的快捷方式 欺骗
for(int i=omp_get_thread_num(); i < n; i+=omp_get_num_threads())
{  
    c[i]=a[i]+b[i];
}
 c[i]=a[i]+b[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];
       }
}
#pragma omp parallel
{
  #pragma omp for
  for (int i = 0; i < n; i++)
    c[i] = a[i] + b[i];
}