OpenMP
開発元 OpenMP ARB
初版 3.1 2011年4月21日 (13年前) (2011-04-21)[1]
最新版
6.0 / 2024年11月24日 (2か月前) (2024-11-24)[2]
対応OS クロスプラットフォーム
プラットフォーム クロスプラットフォーム
前身 無し
後継 無し
サイズ 不明
対応言語
サポート状況 開発中(サポート中)
種別 並列プログラミングAPI、言語拡張
公式サイト www.openmp.org
テンプレートを表示

OpenMP(オープンエムピー)は、並列計算機環境において共有メモリ・マルチスレッド型の並列アプリケーションソフトウェア開発をサポートするために標準化されたAPIである[3]。「OpenMP」は「open multiprocessing」の略である[3]。

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

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

OpenMPは、並列プログラミングにおいて最も広く利用されているAPIであるが、共有メモリに対してUniform Memory Access(英語版)に近いアクセスができるハードウェアシステムアーキテクチャでは、スケーラビリティに限界がある[3]。そのため、現在のほとんどのスーパーコンピューターでは、OpenMP単独ではなく、分散メモリ環境で高いスケーラビリティを発揮するMPIと組み合わせた、ハイブリッドMPI+OpenMPが利用されている[3][6]。

2013年にリリースされたOpenMP 4.0では、多数の先進的な機能が追加された[7]。SIMD命令を使った自動ベクトル化機能(omp simd)や、GPUなどのアクセラレータに並列処理を委譲する分散メモリ型のオフロード機能などがサポートされている[8][9]。

2023年現在、FORTRANとC/C++について標準化が行われている。

OpenMPを用いたコード例

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

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

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

以下は区分求積法を用いた円周率πの数値計算を、OpenMP並列リダクションを用いて行うC++のコード例である。一部にC++11の機能が使われているが、OpenMPのディレクティブ自体は言語バージョンとは無関係であり、C++98/C++03でも利用できる。

#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;
}

#pragma omp parallel forは並列ループのディレクティブである。直後に続くreductionはclause[注釈 2]と呼ばれ、並列処理の動作を調整することができる。ここでは総和を格納するスレッド共有変数sumに対する更新操作の演算子(加算)を指定している。異なるスレッドから共有変数にアクセスするときは排他制御やアトミック操作が必要となるが、OpenMPのclauseを使用することでそのような煩雑なコードを記述する必要がなくなり、詳細を処理系に任せて隠蔽することができる。

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

対応コンパイラ

脚注

注釈

  1. ↑ 実装によっては、スレッドを毎回起動・終了するのではなくスレッドプールが使われる[4][5]。
  2. ↑ 日本語の各種ドキュメントでは、clauseは「指示節」[11]、「文節」[12]、「節」[13]、「句」[14]などと訳されているが、いずれも同じ概念を指す。

出典

  1. ↑ OpenMP 3.1 Released
  2. ↑ OpenMP® ARB Releases OpenMP 6.0 for Easier Programming
  3. 1 2 3 4 Sterling, Thomas; Anderson, Matthew; Brodowicz, Maciej. High performance computing : modern systems and practices. Cambridge, MA. ISBN 9780124202153. OCLC 1013816564
  4. ↑ §Example: /openmp (Enable OpenMP Support) | Microsoft Learn
  5. ↑ 第 4 章 入れ子並列処理 (Sun Studio 12: OpenMP API ユーザーズガイド)
  6. ↑ Rabenseifner, R.; Hager, G.; Jost, G. (2009-2). “Hybrid MPI/OpenMP Parallel Programming on Clusters of Multi-Core SMP Nodes”. 2009 17th Euromicro International Conference on Parallel, Distributed and Network-based Processing: 427–436. doi:10.1109/PDP.2009.43.
  7. ↑ OpenMP 4.0 Specifications Released - OpenMP
  8. ↑ インテル® コンパイラーを使用した OpenMP* による並列プログラミング - セッション 3: OpenMP* の SIMD 機能
  9. ↑ インテル® コンパイラーを使用した OpenMP* による GPU オフロードの基本
  10. ↑ OpenMP* 入門 | iSUS
  11. ↑ OpenMP Application Program Interface Version 3.0 May 2008(日本語版)| 富士通株式会社
  12. ↑ OpenMP ディレクティブの使用 - IBM Documentation
  13. ↑ インテル® Fortran コンパイラーの Fortran 言語と OpenMP* 機能 | iSUS
  14. ↑ OpenMP API ユーザーズガイド - Sun™ Studio 9 | Sun Microsystems, Inc.
  15. ↑ openmp - GCC Wiki
  16. ↑ “Clang 3.7 Release Notes — Clang 3.7 documentation” (英語) (2017年6月4日). 2017年6月4日閲覧。
  17. ↑ OpenMP®/Clang
  18. ↑ Clang 3.9 Release Notes — Clang 3.9 documentation
  19. ↑ OpenMP in Visual C++ | Microsoft Docs
  20. ↑ /openmp (Enable OpenMP Support) | Microsoft Learn
  21. ↑ SIMD Extension | Microsoft Learn
  22. ↑ OpenMP* 4.0 Features in Intel C++ Composer XE 2013 | Intel® Developer Zone
  23. ↑ インテル® Fortran および C++ コンパイラーで実装される OpenMP* 機能の調査 | iSUS

より詳しく知るための本など(For further learning)

洋書:

和書等:

関連項目

外部リンク

⌬ Phoenix Mesh CID: 未登録 IPFS未登録 📡 0ピア N=1 CRITICAL PQS A88