Visual studio メモ1 --OpenMPを使ってfor分を並列化する--
- メニュー>プロジェクト>プロパティ>C/C++>言語>OpenMPのサポート を「はい」にする
- 並列化したいfor文の前に以下を挿入
#pragma omp parallel shared( *, *, ...) num_threads(**)
{
#pragma omp for private(*, *,...)
for1(...){...}
#pragma omp for private(*, *,...)
for2(...){...}
}
#pragma omp parallel for
for1(...){...}
shared( *, *, ...)には,並列化時に全てのスレッドから共有されるメモリ領域を指定する.省略可(明示するかどうかはプログラマ任せで,書かなかったらどうという物ではなさそう.)でもちゃんとした人は書いてるっぽい.
num_threads(**)には,スレッド数を入れる.省略した場合、CPUのコア数が割り当てられるらしい.
private(*, *,...)には,対象forループの外で宣言した変数の内,スレッドがローカルに使いたいものがあれば入れる.↓例.
int x, y;
#pragma omp for private(y)
for( x=0...){
for( y=0...){...}
}
ただ,この例も,
#pragma omp for
for( int x=0...){
for(int y=0...){...}
}
と書けばprivate必要ない.
for ループの中で,変数vの総和を計算する時,以下のように書く.
double v = 0;
#pragma omp parallel for reduction( + : v )
for( int i=0; i<100; ++i){ ...; v+=??; }
スレッド数が4個のときの行われる計算のイメージは以下
まず並列にfor文を計算
スレッド1 : doble v1=0; for( int i= 0; i< 25; ++i){ ...; v1+=??; }
スレッド2 : doble v2=0; for( int i=25; i< 50; ++i){ ...; v2+=??; }
スレッド3 : doble v3=0; for( int i=50; i< 75; ++i){ ...; v3+=??; }
スレッド4 : doble v4=0; for( int i=75; i<100; ++i){ ...; v4+=??; }
for文が終わったら、全ての結果を足し合わせ.
v = v1 + v2 + v3 + v4; |
OpenMPはプログラマを甘やかし過ぎなんじゃないかと思うくらい便利.2行書いただけで数倍高速になったりする。。。