OpenMP 2.0 スレッドのハンドルがリークする

Posted Wed Dec 11 2013

Visual C++ 2008, OpenMP 2.0 にてソフト作成中に,タスクマネージャーを確認していると,スレッド数が増えていく現象に遭遇しました.

Boost.Thread を使用したプログラムだったので,最初は join のし忘れなどをいろいろと疑ったのですが,結果的には OpenMP のバグでした.スレッド内で OpenMP による並列化を行うとスレッドのハンドルがリークします.以下がリークの再現プログラムです.

#include <boost/thread.hpp>

#include <omp.h>

void CalcThread()
{
  double sum = 0.0;
#pragma omp parallel for reduction(+:sum)
  for (int i = 0; i < 1000000000; i++) {
    sum += i;
  }
}

int main()
{
  while (true) {
    boost::thread calc(CalcThread);
    calc.join();
  }

  return 0;
}

回避するには,ループ時にスレッド数を明示してあげればいいみたいです.

void CalcThread()
{
  double sum = 0.0;
#ifdef _OPENMP
  int num_threads = boost::thread::hardware_concurrency();
  omp_set_num_threads(num_threads - 1);
  omp_set_dynamic(num_threads);
#endif
#pragma omp parallel for reduction(+:sum)
  for (int i = 0; i < 100000000000; i++) {
    sum += i;
  }
}

Reference

http://social.msdn.microsoft.com/Forums/en-US/570e3c2a-b53c-4626-8f79-70f57fec4a97/does-openmp-when-used-in-threads-leak-thread-handles-and-memory