C++の並列化 OpenMPとstd::thread

久々にC++触るので肩慣らし。

とりあえず肩慣らしにOpenMPとstd::threadで、ループの数だけスレッド立てる簡単な並列処理を書いてみた。 OpenMP数値計算用途という感じなのかな。。

OpenMP

#include <iostream>
#include <thread>

int main() {
  const int n = 10;
  int array[n];
  for (int i = 0; i < n; ++i) {
    array[i] = 0;
  }

  #pragma omp parallel for
  for (int i = 0; i < n; ++i) {
    std::cout << "begin: " << i << std::endl;
    for (int j = 0; j <= i; ++j) {
      array[i] += j;
    }
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "end: " << i << std::endl;
  }

  std::cout << "-- result --" << std::endl;
  for (int i = 0; i < n; ++i) {
    std::cout << i << ": " << array[i] << std::endl;
  }
}

コンパイルはこんな感じで-fopenmpをつける。

g++ main.cc -o main -fopenmp -O3

std::thread

#include <iostream>
#include <thread>
#include <vector>

void task(int i, int *ary) {
  std::cout << "begin: " << i << std::endl;
  for (int j = 0; j <= i; ++j) {
    ary[i] += j;
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  std::cout << "end: " << i << std::endl;
}

int main() {
  const int n = 10;
  int ary[n];
  for (int i = 0; i < n; ++i) {
    ary[i] = 0;
  }

  std::vector<std::thread> threads;
  for (int i = 0; i < n; ++i) {
    threads.push_back(std::thread(task, i, ary));
  }
  for (auto& thread : threads) {
    thread.join();
  }

  std::cout << "-- result --" << std::endl;
  for (int i = 0; i < n; ++i) {
    std::cout << i << ": " << ary[i] << std::endl;
  }
  return 0;
}

Linuxコンパイルする場合はこんな感じで-lpthreadが必要っぽい。 実態としてはpthreadなんでしょう。 あとstd::threadc++11からなのでstd=c++11が必要な場合もある様子。

g++ main.cc -o main -lpthread