メモの日々


2023年02月21日(火) [長年日記]

[c++] OpenMPの処理結果をスレッド番号順に並べる

先日書いたOpenMPの例は、作られるvectorの要素の順序が毎回変わってしまう。毎回同じ結果を得るにはどうしたらいいか。

の回答を見てなるほどと思った。スレッド数分だけループして、#pragma omp orderedで順番に処理させている。

先日の例に適用してみる。「schedule(static,1)」は指定してもしなくても同じだと思うので指定していない。

#include <iostream>
#include <vector>

#include <omp.h>

std::vector<int> make_vector(int size)
{
  std::vector<int> result;

  #pragma omp parallel
  {
    std::vector<int> local;

    #pragma omp for nowait
    for (int i = 0; i < size; ++i) {
      if (i % 2 == 0) local.push_back(i);
    }

    #pragma omp for ordered nowait
    for (int i = 0; i < omp_get_num_threads(); ++i) {
      #pragma omp ordered
      result.insert(result.end(), local.begin(), local.end());
    }
  }

  return result;
}

int main()
{
  const auto max_threads = omp_get_max_threads();
  std::cout << "max_threads = " << max_threads << std::endl;

  const auto v = make_vector(max_threads * 10);

  std::cout << "v.size = " << v.size() << std::endl;
  for (auto e : v) {
    std::cout << e << ", ";
  }
  std::cout << std::endl;
}
max_threads = 6
v.size = 30
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,