8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Visual Studio C++ で最低限OpenMPをサクッと使う方法

Last updated at Posted at 2020-09-12

#概要
ガッツリイチから解説しているのと、本当に触りのところだけ解説が多い気がしたので、Visual Studio C++で、最低限OpenMPをサクッと使う方法を知りたかった。

#準備
・プロジェクトのプロパティ
C/C++ → 言語 → OpenMP のサポート
を「はい (/openmp)」にする

C/C++ → コマンド ライン に
/Zc:twoPhase-」を追加
(OpenMP時は、2フェーズ名前解決が出来ない、というエラー対策)

#コード
前置きとして、上記設定を行っていなかったとしてもビルド警告が出ず、並列化したつもりが実は出来ていなかったとかありえるので、まずは簡単な処理で並列化して実行してみて、実行順が順不同になったことを確認した方が良いです。
(順不同になったということは、順次実行ではなくなったということで、並列化が効いたと考えられるはず。)

##必要なインクルード

サンプルコード
#include <omp.h>

##for文を並列化

#pragma omp parallel for for () { }

サンプルコード
#pragma omp parallel for
for (int i = 0; i < count; i++) {
    // ここは並列実行される
}

##クリティカルセクションを指定

#pragma omp critical([セクション名]) { }

サンプルコード
int aaaa = 0; // スコープ外の変数は、共有されるので、排他制御が必要
#pragma omp parallel for
for (int i = 0; i < 100; i++) {
    // ここは並列実行される
    int bbbb = 0; // スコープ内のローカル変数は自動でスレッド数分用意される
#pragma omp critical(crit_sct)
    {
        // この内部だけ順次実行される
        aaaa += 1;
    }
    // ここは並列実行される
}

##順番通り(並列化せず)に実行
(ただし、1つのforの中に1つしか書けない)

#pragma omp ordered {}

サンプルコード
int count = 100;
// ordered使う時は、"ordered"句を後ろにくっつけて、どの"parallel for"を順次実行するのか指定する必要がある
#pragma omp parallel for ordered
for (int i = 0; i < count; i++) {
#pragma omp ordered
    {
        // ここは順番通りに実行される
    }
}

#まとめサンプルコード
(この記事には記載していませんが、くれぐれも、mutexなどの排他処理は慎重に)

サンプルコード
#include <iostream>
#include <Windows.h>
#include <omp.h>

int main(void)
{
	const int LOOP_MAX = 10;

#pragma omp parallel for
	for (int i = 0; i < LOOP_MAX; i++) {
		cout << "para. ";
		cout << i << endl;
	}

	cout << endl;

#pragma omp parallel for
	for (int i = 0; i < LOOP_MAX; i++) {
#pragma omp critical(crit_sct)
		{
			cout << "crit. ";
			cout << i << endl;
		}
	}

	cout << endl;

#pragma omp parallel for ordered
	for (int i = 0; i < LOOP_MAX; i++) {
#pragma omp ordered
		{
			cout << "orde. ";
			cout << i << endl;
		}
	}

    Sleep(10000);
    return 0;
}
実行結果
para. 0
para. 1
para. para. 5
para. 6
para. 7
para. 8
para. 9
2
para. 3
para. 4

crit. 5
crit. 6
crit. 7
crit. 8
crit. 9
crit. 0
crit. 1
crit. 2
crit. 3
crit. 4

orde. 0
orde. 1
orde. 2
orde. 3
orde. 4
orde. 5
orde. 6
orde. 7
orde. 8
orde. 9

間違い等あれば、ご指摘いただければ幸いです

#バージョン・規格

また、Visual C++はOpenMP 2.0までしかサポートしていないらしいです。

(ご指摘コメントありがとうございます。)

8
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?