目的
C言語でOpenMPを用いて、並列化を行い高速化を図る場合、思うように高速化がされない場合がある。その一つの例が多重ループを用いた時である。今回は多重ループを持ちいる場合のOpenMPを正しく使う方法を解説する。
TL;DR
多重ループをする場合は、ループの内側だけか両側に #pragma omp parallel for
を置いてあげないといけない。
正解例 (両側配置)
openmp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>
double start,end;
int a[50][40], i, j;
int main(void){
start = omp_get_wtime();
#pragma omp parallel for
for(i = 0; i < 50; i++) {
#pragma omp parallel for
for(j = 0; j < 40; j++) {
a[i][j] = i*j;
}
}
end = omp_get_wtime();
printf("Time:%e(sec)\n",end-start);
return 0;
}
(内側配置)
openmp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>
double start,end;
int a[50][40], i, j;
int main(void){
start = omp_get_wtime();
for(i = 0; i < 50; i++) {
#pragma omp parallel for
for(j = 0; j < 40; j++) {
a[i][j] = i*j;
}
}
end = omp_get_wtime();
printf("Time:%e(sec)\n",end-start);
return 0;
}
計測結果
- OpenMP無し
$ ./a.out
Time:2.463534e-05(sec)
- OpenMP有
$ ./a.out
Time:1.131900e-03(sec)
間違い例
外側だけ配置していると上手く行かない
間違い.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>
double start,end;
int a[50][40], i, j;
int main(void){
start = omp_get_wtime();
#pragma omp parallel for
for(i = 0; i < 50; i++) {
for(j = 0; j < 40; j++) {
a[i][j] = i*j;
}
}
end = omp_get_wtime();
printf("Time:%e(sec)\n",end-start);
return 0;
}