OpenMP for文を並列実行する
提供: C言語入門
スポンサーリンク
OpenMPではプラグマ #pragma omp parallel forを使用して、for文を並列実行できます。
- pragma omp parallel for
- ぷらぐま おーえむぴー ぱられる ふぉー
目次
概要
for文をパラレルに実行できます。for文のブロックがスレッドで処理されます。 OpenMPのスレッドIDをomp_get_thread_num()で取得できるので、ループカウンタの値がどのスレッドにわたっているのかも見てみましょう。
#pragma omp parallel for for(i = 0; i < 32; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); }
は、スレッドが4つの場合、以下のように分担されます。実際の実行例は、 omp_get_thread_num1.c のサンプルを実行した結果をこのページの下のほうに掲載してあります。
//スレッド 0 for(i = 0; i < 8; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); } //スレッド 1 for(i = 8; i < 16; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); } //スレッド 2 for(i = 16; i < 24; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); } //スレッド 3 for(i = 24; i < 32; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); }
もしスレッドが2つなら、0から15と16から31で分担されます。
openmp_for1.c の例
ソースコード openmp_for1.c
/* * hello.c * Copyright (C) 2014 kaoru <kaoru@bsd> * * Distributed under terms of the MIT license. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <omp.h> int main(int argc, char *argv[]) { size_t i; #pragma omp parallel for for(i = 0; i < 10; ++i) { sleep (1); printf("hello world: %lu\n", i); } exit(EXIT_SUCCESS); }
コンパイル
gcc49 \ -Wl,-rpath=/usr/local/lib/gcc49 -fopenmp openmp_for1.c -o openmp_for1
実行例
コアが2つの環境で実行した例です。1つ目は、スレッド数を16と環境変数で指定しているため、10スレッド実行されています。よって、1秒程度で実行が完了しています。2つ目は、スレッド数は指定しないため、コア数2の環境で実行したため、スレッドが2つずつ実行されます。2スレッドx5回で10回実行されるため、5秒程度かかっています。
$ /usr/bin/time env OMP_NUM_THREADS=16 ./openmp_for1 hello world: 0 hello world: 8 hello world: 5 hello world: 9 hello world: 7 hello world: 4 hello world: 6 hello world: 3 hello world: 2 hello world: 1 1.05 real 0.00 user 0.00 sys $ /usr/bin/time ./openmp_for1 hello world: 0 hello world: 5 hello world: 1 hello world: 6 hello world: 2 hello world: 7 hello world: 3 hello world: 8 hello world: 9 hello world: 4 5.18 real 0.00 user 0.00 sys
スレッドとfor文の扱いを調べる omp_get_thread_num1.c の例
ソースコード omp_get_thread_num1.c
/* * hello.c * Copyright (C) 2014 kaoru <kaoru@bsd> * * Distributed under terms of the MIT license. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <omp.h> int main(int argc, char *argv[]) { size_t i; #pragma omp parallel for for(i = 0; i < 32; ++i) { printf("%d: %lu\n", omp_get_thread_num(), i); } exit(EXIT_SUCCESS); }
コンパイル
gcc49 \ -Wl,-rpath=/usr/local/lib/gcc49 -fopenmp omp_get_thread_num1.c -o omp_get_thread_num1
実行例
$ /usr/bin/time env OMP_NUM_THREADS=4 ./omp_get_thread_num1 1: 8 1: 9 1: 10 1: 11 1: 12 1: 13 1: 14 1: 15 0: 0 0: 1 0: 2 0: 3 0: 4 0: 5 0: 6 0: 7 2: 16 2: 17 2: 18 2: 19 2: 20 2: 21 2: 22 2: 23 3: 24 3: 25 3: 26 3: 27 3: 28 3: 29 3: 30 3: 31 0.00 real 0.00 user 0.00 sys
関連項目
- OpenMPとは
- OpenMP ブロックを並列実行する
- OpenMP for文を並列実行する
- OpenMPでのアトミックな処理
ツイート
スポンサーリンク