2016-11-23 5 views
1
# include <iostream> 
# include <cstdlib> 
# include <omp.h> 

#define SIZE 10 
#define NUM_THREADS SIZE 

using namespace std; 

main() { 

omp_lock_t lock; 
//omp_init_lock(&lock); 

srand(time(NULL)); 

int arr[SIZE], max = -1; 

omp_set_num_threads(NUM_THREADS); 

for(int i = 0; i < SIZE; i++) 
    arr[i] = rand()%100; 

#pragma omp parallel for 
for(int i = 0; i < SIZE; i++) { 
    omp_set_lock(&lock); 
     if(arr[i] > max) 
      max = arr[i]; 
    omp_unset_lock(&lock); 
} 

cout << "Max: " << max << endl; 

}omp_init_lock(omp_lock_t *) - この関数は正確に何をしますか?

これはコードですが、私はOpenMPのロック機能を使用して、配列内の最大の要素を見つけるために書きました。その関数omp_init_lockをスキップすると、私のコードは実行されません。それでもコンパイルは成功しますが、アレイのSIZEが小さい場合(10または20のような)の場合は、すべてのスレッドがforループに入った後に終了します。それ以外のときは問題なく実行されます(配列のサイズが100のように大きい場合)。

しかし、omp_init_lock()はすべての問題を解決します。どうやって?私は検索しましたが、それについてはあまり見つけられませんでした。ロックされていない状態にロックを初期化するということだけが言及されました。ロックを初期化しないのに配列のサイズが100のときにコードが実行されるのはなぜですか?

omp_init_lock()は具体的にどのような処理をしていますか?

答えて

0

omp_init_lockの機能は、設定/解除のロック変数を初期化しているようです。これには、ロックに使用される必要なメモリーを割り振り、初期状態を「ロック解除」に設定することが含まれます。適切な初期化がなければ、予期しない結果が予想されるはずです。

OMP_INIT_LOCKロック変数に関連付けられているロックを初期化

出典:LLNL OpenMP Tutorials

3

アンOpenMPのロックは、3つの可能な状態にあることができる:をいないに関わらず、アンロック、又はOpenMP specificationの3.3節)。宣言されているが、omp_init_lock()への呼び出しで初期化されていない場合、ロックはunitialized状態になります。 omp_init_lock()を呼び出すと、ロックがのロックが解除された状態に遷移します。それ以降は、ロックはのロックを使用し、のロックを解除したを使用してomp_unset_lock()を使用してロックすることができます。

初期化されていない状態にあるロックでomp_set_lock()を呼び出すと、エラーが発生します(3.3.4項)。 がロックされていないがロックされたを含むのロックにomp_unset_lock()を呼び出すと、間違っています(3.3.5項)​​。あなたのプログラムが正常にロックを初期化せずに特定の条件で動作

不定動作です。

+0

ありがとうございます。 :)少なくとも、ロックの状態が初期化されていないことを人々に知らせるために、警告またはエラーをスローする必要があります。しかたがない。 –

+0

ロック操作はできるだけ速いと考えられているので、毎回ロック変数をチェックするだけでは実用的ではありません。スレッドアナライザ(Oracle Solaris Studioの一部、元Sun Studio)のような、コード内のそのような問題を検出する正しさチェックツールがあります。 –

関連する問題