OpnMP(Openm Multi-Processing)は、1つのマシン内で並列計算を行うためのAPIです。
FORTRANとC(C++)で利用ができます。今回は、C++を例に用いて説明します。
並列計算
並列計算は、計算対象を複数のタスクに分けることで、各コアで並行して処理できるようにします。
小分けにしたタスクはスレッドと呼ばれ、スレッドをコアに割り振ります。
プログラム全てを並列化できることはほとんどありません。基本的にはプログラムの一部だけ並列処理を行うのが一般的です。
最も並列化に適した部分を並列化してあげる必要があるので、並列化する上でプログラムの知識は欠かせません。
OpenMPの書き方
ここからは実際にOpenMPを利用していきましょう。すでに環境がある前提で説明を行うので、環境構築に関しては他のサイトを参考にしてください。
まず、OpneMPのライブラリをインクルードする必要があります。インクルードには、プログラムの冒頭に#include <omp.h> と記述してください。
処理の複数実行
次に、既存のプログラムの並列化を行います。並列化には2通りの代表的な方法があります。
一つは対象の処理をスレッド数分行うというものです。下記のように #pragma omp parallel とブラケットで対象の処理を囲います。
#include <stdio.h>
#include <iostream>
#include <omp.h>
int main(){
#pragma omp parallel{
printf("Hello \n");
}
}
上記のプログラムでは、printfの部分がOpneMPの対象として囲まれているので、スレッドの数だけ画面に「Hello」が表示されることになります。
for分の展開
2つ目の方法はfor文の展開です。既存のプログラムの高速化として使いやすいので、こちらのほうがよく利用されます。
こちらは、すでにあるfor文を並列により高速化するという方法です。
先程の記述に加えて、for文の前に #pragma omp for を書くだけでfor文を展開して並列化してくれます。
#include <stdio.h>
#include <iostream>
#include <omp.h>
int main(){
int x[100],y[100],z[100];
#pragma omp parallel{
#pragma omp for
for(int i=0; i<100; i++){
x[i] = 1;
y[i] = 2;
}
#pragma omp for
for(int i=0; i<100; i++){
z[i] = x[i] + y[i];
}
}
}
上記だと、for文は全てスレッドで並列化されることになります。
下記のように #pragma omp parallel for を使うことで簡略化して書くことができます。
#include <stdio.h>
#include <iostream>
#include <omp.h>
int main(){
int x[100],y[100],z[100];
#pragma omp parallel for
for(int i=0; i<100; i++){
x[i] = 1;
y[i] = 2;
}
#pragma omp parallel for
for(int i=0; i<100; i++){
z[i] = x[i] + y[i];
}
}
}
簡略化によりブラケットを省略することができるので、コードが非常に見やすくなります。こちらの書き方が一般的です。
例えば、100回ループで4スレッドなら、各スレッドで25回分のループが実行されます。
ここで注意ですが、forループを並列化する場合は、各ループで相互参照がないことを事前に確認しておきましょう。
数値解析では、陽的な処理であれば基本的に並列化が可能です。
実行
一般的なコンパイラであれば、OpenMPに対応しています。そのため、上記のプログラムを与えてやれば、コンパイル時に並列化用の実行ファイルを作成してくれます。
ここではgccコンパイラを例に説明します。
OpenMPを使うときは、コンパイラオプションに「-fopenmp」を加えます。
また、環境変数に「OMP_NUM_THREADS」を追加して、スレッド数を与えます。例えば、redhatもしくはcentos系Linuxだと「export OMP_NUM_THREADS=4」をコマンドラインで実行してやれば良いです。
以上を行うことで、OpenMPによる並列化が行えます。
おわりに
今回はOpenMPを使用したノード内並列化について説明しました。
重要なポイントは下記の通りです。
- 並列計算では、プログラムの一部が並列化される
- OpenMPは並列計算の規格であり、プログラムの修正により並列計算できるようになる
- OpenMPは一つのマシン(ノード)内で並列計算ができる
- OpenMPを使うには、ライブラリをインクルードする
- OpenMPでは、#pragma omp parallel とブラケットで並列部分の指定を行う
- #pragma omp for によりfor文を並列処理できる
- 実行時は、 -fopenmp のオプションを加えてコンパイルする
- 並列数は環境変数にて事前に指定する
特に、for文の展開による並列化は簡単にプログラムを高速化できるため、非常に有用です。
並列計算は今回紹介したOpneMPとマシン(ノード)間を並列化させるMPIがあります。
OpenMPのほうが簡単なので、手軽に並列計算をしたい場合はOpenMPからまずは行いましょう。
youtubeもやってます
Linuxに関する解説を動画で行っています。基本的な内容に不安のある方はこちらもどうぞ。