マルチプロセッサによる並列処理が簡単に記述できるOpenMP。標準で対応しているコンパイラが多いもかかわらず使用したことがありませんでした。ラズパイで配列などの単純な計算に使いたいと思いテストしてみました。
しかしこれ以前扱ったことがあるかも・・と検索してみたら、OpenMPIのことでした。
間違えやすいですね。
下記、とても詳しいドキュメントがあります。
https://www.cc.u-tokyo.ac.jp/events/lectures/03/kosyu-openmp_c.pdf
mp1.c
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include<stdio.h> #include<omp.h> int main() { printf("%d\n", omp_get_max_threads()); int i = 0; #pragma omp parallel { printf("Hello! : %d\n", i ++); } } |
コンパイルオプション
cc -o mp1 mp1.c -fopenmp -O3
プラグマ(コンパイラへの指示内容を記述)でプログラムの実行結果が変化します。4つのコアがあれば4回表示されます。
下に、実行結果比較があります。(nmp1 というのは、OpenMP部分をコメントして通常どおりコンパイルしたもの)
mp2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include<stdio.h> #include<omp.h> #include<time.h> int main() { struct timespec start, end; int n = omp_get_max_threads(); printf("%d\n", n); long i = 0; double sum = 0.0; clock_gettime(CLOCK_MONOTONIC, &start); #pragma omp parallel for private(i) reduction(+:sum) for(i = 0; i < 1000000L; i++){ sum += 0.01; } clock_gettime(CLOCK_MONOTONIC, &end); printf("sum: %lf\n", sum); printf("time: "); if (end.tv_nsec < start.tv_nsec) { printf("%ld.%09ld", end.tv_sec - start.tv_sec - 1, end.tv_nsec + 1000000000 - start.tv_nsec); } else { printf("%ld.%09ld", end.tv_sec - start.tv_sec, end.tv_nsec - start.tv_nsec); } printf("\n"); } |
実行時間を計測してみました。
(その他 mp1と同様)
結果は毎回かわりますが、このあたりのスレッドのコントロールも細かくできそうです。
もう少し勉強してみたいです。