- 締切済み
VC++上でのOpenMPの使用に関しての質問です
VC++2010でOpenMPを使い始めて間もないので、初歩的な質問かもしれませんが、検索しても解決できなかったため、ここで質問させてください。 以下のプログラムについてです。 これを実行すると "lCount=10001"が出力されるはずですが、 "lCount=5000"とか10001以外の数値が出力されてしまいます。 原因が分からず困っています。よろしくお願いします。 ちなみに、クラスCTest は何もしていませんが、以下のいずれかを 行うと"lCount=10001"が出力されるようになります。 ・07~09行目をコメント ・24行目をコメント ========================================= 01>#include <stdio.h> 02>#include <omp.h> 03> 04>class CTest 05>{ 06>public: 07> CTest() 08> { 09> } 10> 11> long m_lTT; 12>}; 13> 14>void main() 15>{ 16> long lCount = 0; 17> long i; 18> 19> ::omp_set_num_threads(10); 20> 21> #pragma omp parallel for 22> for(i = 0; i <= 10000; i++) 23> { 24> CTest aa[100]; 25> #pragma omp critical 26> { 27> lCount++; 28> } 29> } 30> 31> printf("lCount=%d\n", lCount); 32> _fgetchar(); 33>} =========================================
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- kmee
- ベストアンサー率55% (1857/3366)
OpenMPはちょっとかじった程度ですが。 多分、変数の私有(private)と共有(shared)が、期待通りに割り振られていないのだと思います。 #pragma omp parallel for shard(iCount) private(i) ではどうでしょう? > #pragma omp critical 全スレッドがここを通る度に待つので非常に効率が悪くなります。本当にクリティカルな処理以外は使わない方がいいです。 今回のだったら reduction が使えます。 >行うと"lCount=10001"が出力されるようになります。 >・07~09行目をコメント >・24行目をコメント おそらく、ループ最適化により 全て定数で計算の必要無し →「iCount=10001」というコードを生成 となっているものと思われます。 コンストラクタを記述したときは「デフォルトではないなにかをしている可能性がある」と判断して、真面目にループするのかと。
お礼
早速の回答有難うございます。 kmeeさんのご指摘された通り shared(lCount) private(i) を追加して試しましたが症状は改善されませんでした。う~ん何がおかしいでしょう。。。 その他、kmeeさんのご指摘の通り、このプログラムにおいては、critical ではなく reduction が適切ですね。冒頭で触れておけば良かったのですが、このプログラムは現在私が作成しているプログラムの一部分でして、critical のブロック内には他のコマンドもあります。そのため、reduction に置き換えることは難しいです。 何か文法上の問題であれば良いのですが…。
補足
本日、標準インストールしたVineLinux6.0上で、同じプログラムを実行させてみました。正常に動いており、"lCount=10001"が出力されます。^^; ループ回数を様々に変更してみましたが、正常な値が出力されています。何が原因でしょう。。。バグ?