OpenMP

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索
OpenMP
開発元 OpenMP ARB
最新版 4.0 / 2013年7月23日(19か月前) (2013-07-23
プログラミング言語 C/C++, Fortran
プラットフォーム クロスプラットフォーム
種別 並列プログラミングAPI、言語拡張
公式サイト www.openmp.org
テンプレートを表示

OpenMPは、並列コンピューティング環境を利用するために用いられる標準化された基盤。OpenMPは主に共有メモリ型並列計算機で用いられる。

MPIでは明示的にメッセージの交換をプログラム中に記述しなければならないが、OpenMPはOpenMPが使用できない環境では無視されるディレクティブを挿入することによって並列化を行う。このため並列環境と非並列環境でほぼ同一のソースコードを使用できるという利点がある。 また、プラットフォーム固有のスレッドAPIを使わず、コンパイラによって暗黙的に生成されたスレッドプールを利用してタスクを振り分けることになるため、並列プログラムを簡潔に記述できるだけでなく、複数の環境に移植しやすくなる。

MPIとの比較では、OpenMPは異なるスレッドが同一のデータを同じアドレスで参照できるのに対して、MPIでは明示的にメッセージ交換を行わなければならない。そのためSMP環境においては大きなデータの移動を行なわずにすむので高い効率が期待できる。ただし並列化の効率はコンパイラに依存するのでチューニングによる性能改善がMPIほど高くならないという問題がある。また、OpenMPはMPIに比べてメモリアクセスのローカリティが低くなる傾向があるので、頻繁なメモリアクセスがあるプログラムでは、MPIの方が高速な場合が多い[要出典]

現在FORTRANC/C++について標準化が行われている。

OpenMPを用いたコード例[編集]

以下はC言語における for ループを並列処理させる例である。

int main(int argc, char *argv[])
{
    int i;
#pragma omp parallel for
    for (i = 0; i < 10000; ++i)
    {
        // (並列処理させたいプログラム)
    }
}

OpenMPはループの反復処理を自動的に複数のスレッドに分割して並行処理できるようにする。例えば4つのスレッドを用いて処理を分割する場合、上記例ではインデックス[0, 2499], [2500, 4999], [5000, 7499], [7500, 9999]の各範囲をそれぞれのスレッドに分担させる、といった具合である。実際にいくつのスレッドを起動するのか、また各スレッドに対してどのように処理を振り分けるのかはOpenMP処理系およびプログラム実行環境などの条件に依存する[1]

以下は区分求積法を用いた円周率πの数値計算を、OpenMP並列リダクションによって行なうC++のコード例である。

#include <iostream>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <omp.h>
 
const double D_PI = 3.1415926535897932384626433832795;
 
// 区分求積法で π の近似値を求める。
// 1 / (x^2 + 1) を区間 [0, 1] で積分すると π/4 になるという定積分を利用する。
 
int main()
{
  const int DivNum = 1000 * 1000 * 1000;
  const double delta = 1.0 / DivNum;
 
  std::cout << "OpenMP max threads count = " << omp_get_max_threads() << std::endl;
 
  const auto startTime = std::chrono::system_clock::now();
  double sum = 0;
#pragma omp parallel for reduction(+ : sum)
  for (int i = 0; i < DivNum; ++i)
  {
    const double x = (delta * i);
    const double area = delta *  1.0 / (x * x + 1.0);
    sum += area;
  }
  const double pi = sum * 4.0;
  const auto endTime = std::chrono::system_clock::now();
  std::cout << std::setprecision(15) << "PI ~= " << pi << std::endl;
  std::cout << "Error [%] = " << (100.0 * std::fabs(D_PI - pi) / D_PI) << std::endl;
  std::cout << "Elapsed time [ms] = " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << std::endl;
  return 0;
}

OpenMPコンパイルオプションの有無を切り替えるか、OpenMPディレクティブをコメントアウト/コメント解除してからコンパイル・実行することで、マルチスレッド版およびシングルスレッド版の速度性能比較を簡単に行なうことができるのがOpenMPプログラムの特徴である。

対応コンパイラ[編集]

脚注[編集]

関連項目[編集]

参考文献(学習用)[編集]

  • Rohit Chandra, Ramesh Menon, Leo Dagum, David Kohr, Dror Maydan and Jeff McDonald: "Parallel Programming in OpenMP" , Morgan Kaufmann, ISBN 978-1558606715,(2000年10月).
  • Barbara Chapman,Gabriele Jost and Ruud Van der Pas: "Using OpenMP: Portable Shared Memory Parallel Programming", ISBN 978-0-262-53302-7, MIT Press, (2007年10月).
  • 牛島 省:「OpenMPによる並列プログラミングと数値計算法」,丸善、ISBN 978-4621077177、(2006年5月).
  • 菅原 清文:「C/C++ プログラマーのための OpenMP 並列プログラミング」、カットシステム、ISBN 978-4-87783-223-0 (2012年6月).

外部リンク[編集]