目次 >> OpenMP
OpenMPは複数のCPU(複数コアを含む)を持った計算機上での並列化に威力を発揮する。
OpenMPを使う最大の利点は、OpenMPに対応したコンパイラであれば、非常に簡単に並列化できる点である。
現在、gcc、Visual C++、およびIntelコンパイラなど主要なコンパイラはOpenMPに対応している。
習得も他の並列か技法に比べて比較的容易である。
なお、速度を最優先にする場合、単一コンピュータ上で動かした場合でも、OpenMPよりMPIの方が効率のよいことが多い。
なお、インテルがOpenMP初心者向けに非常にわかりやすい文書を公開している。
OpenMPの各種関数を使わない場合、#pragma ompで始まる指示をソースコード内に書き込み、下記のコンパイルスイッチをつけてコンパイルするだけで、並列化される。
インテルコンパイラ(icpc)の場合は、Linux用では-openmpを、Windows用では、/Qopenmpをつけてコンパイルする。なお、インテルコンパイラは、バージョン9よりAMDのプロセッサにも対応するようになったが、バージョン9とAMDプロセッサの組み合わせでのOpenMPはなぜが実行効率が非常に悪い。これはバージョン10にすることにより解決される。
Visual C++(cl)の場合は、/openmpをつけてコンパイルする。
Visual C++は2005よりOpenMPがサポートされている。なお、無料のExpressバージョンには含まれていないが、Windows
SDK for Windows Server 2008 and .NET Framework 3.5を導入することによって、使えるようになる。詳細はこちら。
gcc(g++)の場合は、-fopenmpをつけてコンパイルする。GCCはバージョン4.2から正式にサポートされるようになった。
ここではOpenMPを使った並列計算について解説する。
OpenMPを使ってコンパイルしているかをプログラム中で知るには、_OPENMPが定義されているかで判別します。具体的には、
#ifdef _OPENMP
//OpenMPを使ったコード
#else
//OpenMPを使わない場合のコード
#endif
#pragma omp parallel forを使います。
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
下記のように書くと毎回forループに入るたびにスレッドの生成コストが発生する。
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
下記のようにすると、スレッド生成は一回ですむ。
#ifdef _OPENMP
#pragma omp parallel
#endif
{
#ifdef _OPENMP
#pragma omp for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
#ifdef _OPENMP
#pragma omp for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
#ifdef _OPENMP
#pragma omp for
#endif
for(int i=0;i<N;i++)
{
//ここの処理を書く
}
}
#pragma omp parallel および#pragma omp sectionsを使います。
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
{
//並列させたい処理1
}
#pragma omp section
{
//並列させたい処理2
}
#pragma omp section
{
//並列させたい処理3
}
}
通常は、環境変数OMP_NUM_THREADSから取得して並列数が決まる。omp_set_num_threads関数を使うと、プログラム中で指定できる。
#ifdef _OPENMP omp_set_num_threads(4); #endif
omp_get_max_threads()関数を使う。
#ifdef _OPENMP cout<<"OpenMP : Enabled (Max # of threads = "<<omp_get_max_threads()<<")"<<endl; #endif