2008年9月28日日曜日

OpenMP 入門 #2

林檎生活100: OpenMP 入門 #1 の続き.OpenMP をやっていこう.今回は,for ディレクティブについてだね.正直,やってみたんだけど速くなってるかどうかわかんなかったwww

for ディレクティブってのは,そのまま for ループを並列化するためのディレクティブ.たとえば,次のような for ループを考えてもらうとわかりやすい.

for (i = 0; i < 100; i++)
c[i] = a[i] + b[i];


このループを,CPU が2つなら,それぞれの CPU に50回ずつやらせれば,2倍のスピードで計算できるよねって考え方だ.安直に分割するとこうなる.

・CPU1
for (i = 0; i < 50; i++)
c[i] = a[i] + b[i];


・CPU2
for (i = 50; i < 100; i++)
c[i] = a[i] + b[i];


これを,OpenMP でやるときに for ディレクティブを使う.for ディレクティブで書いてみるとこんなかんじになるらしい.

#include <omp.h>

#define CHUNKSIZE 100
#define N 1000

int main(void)
{
int chunk;
int i;
float a[N];
float b[N];
float c[N];

chunk = CHUNKSIZE;
for (i = 0; i < N; i++) {
a[i] = (float)i;
b[i] = (float)i;
}

#pragma omp parallel shared(a, b, c, chunk) private(i)
{
#pragma omp for schedule(dynamic, chunk) nowait
for (i = 0; i < N; i++)
c[i] = a[i] + b[i];
}

return 0;
}


これをコンパイルして実行すると,当然画面には何もでない.omp_get_num_threads() で調べてみたら,たしかにスレッド数は2になってた.うーん,速くなってんのかな?w

ディレクティブのオプションについて簡単に.

shared:スレッドの共有変数を指定している.
private:スレッドのプライベート変数を指定している.
schedule:ループをどうやって分割するかについて.引数に dynamic を指定すると,chunk サイズごとに空いているスレッドに動的に割り当てる.
nowait:for ディレクティブによって自動的に同期が取られるところで同期をとらない.

というかんじ.あってるかあやしいwいずれ書き直しになりそうな予感がする.ちゃんと本とか買って勉強した方が良さそうだなぁ.

参考文献:
OpenMP Tutorial

0 件のコメント: