では、OpenMPを使ったときにどれだけ速くなるか?
知りたいですよね?
そこで、OpenMPの時間計測関数を使います。使い方はMPIの
MPI_Wtime()関数と同じです。
では、早速使ってみましょう。
002-1.c
#include<stdio.h>
#include<omp.h>
int main(int argc,char *argv[])
{
int my;
double start,end;
start = omp_get_wtime();
#pragma omp parallel
{
my = omp_get_thread_num();
printf("hello world!! I'm %d !!\n",my);
}
end = omp_get_wtime();
printf("elapsed time = % lf \n",(end-start));
return 0;
}
計測したいところの前後にomp_get_wtime()関数を埋め込むことで実行時間が計測できます。では、測った結果を見てみましょう。
$ gcc -fopenmp 002-1.c -o 002-1
$ ./002-1
hello world!! I'm 2 !!
hello world!! I'm 6 !!
hello world!! I'm 5 !!
hello world!! I'm 3 !!
hello world!! I'm 0 !!
hello world!! I'm 7 !!
hello world!! I'm 4 !!
hello world!! I'm 1 !!
elapsed time = 0.002606
計測できているみたいですね。では、これだけだとあまり面白くないのでもっと実行時間のかかるものを計測してみましょう。
002-2.c
#include<stdio.h>
#include<omp.h>
#define N 1000000
int main(int argc,char *argv[])
{
int my,n;
int i,A[N];
double start,end;
start = omp_get_wtime();
for (n=0;n<1000;n++)
{
#pragma omp parallel for
for (i = 0 ; i < N ; i++)
A[i]=i;
}
end = omp_get_wtime();
printf("elapsed time = % lf \n",(end-start));
return 0;
}
このプログラムでは、ループを並列化しているのですが、その詳しい方法は後ほどお教えするとして、まずは上のプログラムをコンパイルして実行してみましょう。その際環境変数を使って自分の持っているCPUのコア数分だけ並列化してみるのをお忘れなく。
$ gcc -fopenmp 002-2.c -o 002-2
$ OMP_NUM_THREADS=1 ./002-2
elapsed time = 1.652859
$ OMP_NUM_THREADS=2 ./002-2
elapsed time = 0.832492
$ OMP_NUM_THREADS=3 ./002-2
elapsed time = 0.565996
$ OMP_NUM_THREADS=4 ./002-2
elapsed time = 0.424413
$ OMP_NUM_THREADS=5 ./002-2
elapsed time = 0.344338
$ OMP_NUM_THREADS=6 ./002-2
elapsed time = 0.286859
$ OMP_NUM_THREADS=7 ./002-2
elapsed time = 0.250896
$ OMP_NUM_THREADS=8 ./002-2
elapsed time = 0.231162
どうでしょうか?それっぽく並列化の効果が現れていますね。
でも、コア1個とコア8個の実行時間を比べた時に速度比が
1.652859/0.231162≒7.15
と、8倍にはなっていないですね、これものちほど説明していきたいと思います。
世の中にはOpenMPのどこにどれくらい時間がかかっているか詳しく計測してくれるアプリケーションがありますが、当面はこれだけで乗り切ります。詳しく知りたいかたは調べてみてください。
今回はここまで。