Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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与for循环并行的行为_C++_Parallel Processing_Openmp - Fatal编程技术网

C++ pragma omp与for循环并行的行为

C++ pragma omp与for循环并行的行为,c++,parallel-processing,openmp,C++,Parallel Processing,Openmp,我似乎并不完全理解带有嵌套for循环的openmp并行结构的行为。考虑下面的代码: std::size_t idx; std::size_t idx2; omp_set_num_threads( 2 ); #pragma omp parallel default(shared) private(idx, idx2) { for(std::size_t idx=0;idx<3;idx++) { for(std::size_t idx2=0;idx2<4;idx2++

我似乎并不完全理解带有嵌套for循环的openmp并行结构的行为。考虑下面的代码:

std::size_t idx;
std::size_t idx2;
omp_set_num_threads( 2 );

#pragma omp parallel default(shared) private(idx, idx2)
{

  for(std::size_t idx=0;idx<3;idx++)
  {
    for(std::size_t idx2=0;idx2<4;idx2++)
    {
      LOG("From thread "+std::to_string(omp_get_thread_num())+" idx "+std::to_string(idx)+" idx2 "+std::to_string(idx2));
    }
  }
}
上面出现的情况是,分配了两个线程来执行两个嵌套循环,因此它们生成了上述输出(总共2*3*4=24条日志消息),这很简单

但是现在考虑下面的代码,其中内部for循环被声明为<代码>

std::size_t idx;
std::size_t idx2;    
omp_set_num_threads( 2 );

#pragma omp parallel default(shared) private(idx, idx2)
{

  for(std::size_t idx=0;idx<3;idx++)
  {
    #pragma omp for
    for(std::size_t idx2=0;idx2<4;idx2++)
    {
      LOG("From thread "+std::to_string(omp_get_thread_num())+" idx "+std::to_string(idx)+" idx2 "+std::to_string(idx2));
    }
  }
}
我希望再次将两个线程分配给对应于两个内部for循环的代码,并再次获得24条输出消息。为什么这两种情况下的输出不同?

在第一种情况下,在每个线程上运行整个并行区域一次。这意味着两个线程将完全运行这两个for循环,因此每个线程应该生成4*3=12行输出

在第二种情况下,内部
#pragma omp for
告诉计算机,
idx2
上的内部for循环应该在可用线程之间分割。因此,不是两个线程都执行从0到
idx2
的内部循环,而是内部循环的每个迭代将只执行一次

在第二个输出中,我们应该看到,
idx2
的所有值对于
idx
的每个值都被精确地打印一次,并且来自任何碰巧可用的线程

e、 g.如果
idx
只能为零,则输出可能类似于:

From thread ? idx 0 idx2 0
From thread ? idx 0 idx2 1
From thread ? idx 0 idx2 2
From thread ? idx 0 idx2 3

其中
表示它可以是任何可用线程。

\pragma omp for在所有可用线程之间分配idx2范围,如第二种情况。在第一种情况下,您没有使用
for
语句,因此每个线程都会在整个idx2范围内迭代。@GavinPortwood,听起来这应该是一个答案。:)
From thread 0 idx 0 idx2 0
From thread 1 idx 0 idx2 2
From thread 0 idx 0 idx2 1
From thread 1 idx 0 idx2 3
From thread 0 idx 1 idx2 0
From thread 1 idx 1 idx2 2
From thread 0 idx 1 idx2 1
From thread 1 idx 1 idx2 3
From thread 0 idx 2 idx2 0
From thread 0 idx 2 idx2 1
From thread 1 idx 2 idx2 2
From thread 1 idx 2 idx2 3
From thread ? idx 0 idx2 0
From thread ? idx 0 idx2 1
From thread ? idx 0 idx2 2
From thread ? idx 0 idx2 3