OpenMP for文を並列実行する

提供: C言語入門
2014年5月11日 (日) 22:33時点におけるDaemon (トーク | 投稿記録)による版 (コンパイル)

移動: 案内検索
スポンサーリンク

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

関連項目




スポンサーリンク