openmp:有序调度(静态)块序列

时间:2017-01-05 18:31:25

标签: for-loop parallel-processing openmp

我有这个序列号:

std::vector<T> input, output;
//populate input
for (size_t i=0 ; i < input.size() ; i++){
  output.push_back(//something using input[i]);
}

请注意,使用output[i]计算input[i]至关重要。现在我想并行化它。一个简单的解决方案是:

std::vector<T> input, output;
//populate input
#pragma omp for schedule(dynamic) ordered  
for (size_t i=0 ; i < input.size() ; i++){
  #pragma omp ordered
  output.push_back(//something using input[i]);
}

然而,这可能是非常低效的(ordered需要获得锁定,如果执行多次会产生很大的开销,此外如果块大小很小,则会产生更多的开销)。另一种可能的解决方案是分别填充每个块,然后合并它们(以有序的方式):

std::vector<T> input, output;
//populate input
#pragma omp parallel
{
  std::vector<T> myOutput;
  std::vector<int> myIndexes;
  #pragma omp for schedule(static,1)  //NOTICE STATIC!
  for (size_t i=0 ; i < input.size() ; i++){
    myOutput.push_back(//something using input[i]);
    myIndexes.push_back[i];
  }
  #pragma omp for ordered schedule(static)
  for(int i=0 ; i<omp_get_num_threads() ; i++){
    #pragma omp ordered
    {
      std::cout<<"Hello from thread "<<omp_get_thread_num()<<": ";
      for(size_t j = 0; j < myIndexes.size(); j++)
        std::cout<<indexes[j]<<" ";
      std::cout<<std::endl;
    }
  }
}

假设input.size()=10我们有8个核心。这就是我想要打印的内容:

Hello from thread 0: 0 1 
Hello from thread 1: 2 3 
Hello from thread 2: 4
Hello from thread 3: 5 
Hello from thread 4: 6 
Hello from thread 5: 7 
Hello from thread 6: 8 
Hello from thread 7: 9

但是这个是它实际印刷的内容:

Hello from thread 0: 0 8 
Hello from thread 1: 1 9 
Hello from thread 2: 2  
Hello from thread 3: 3 
Hello from thread 4: 4 
Hello from thread 5: 5 
Hello from thread 6: 6 
Hello from thread 7: 7 

this问题中的代码可以解决我的问题,但这有点作弊(它实际上并没有使用#pragma omp parallel for)。

是否可以仅使用openmp获得我想要的行为?

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是使用operator[]代替push_back

std::vector<T> input, output;
//populate input
output.resize(input.size())
#pragma omp parallel for
for (size_t i=0 ; i < input.size() ; i++){
  output[i] = //something using input[i]);
}

现在假设T DefaultInsertable 。如果没有,您可以使用resize的特定虚拟值参数。

BTW:我不明白你的预期输出。为什么您希望索引在不同的线程上多次出现?

编辑:

OpenMP规范清楚地说明了static调度(表2.5)。

  

分配了块   团队中的线程以线程的顺序循环方式   号。

所以实际结果是符合的。