OpenMPの奇妙な動作

Hello I have the following code, which I compile with gcc (>4.2) with -fopenmp flag:

int main(void)
{
#pragma omp parallel for
    int i; 
    for(i=0;i<4;i++) while(1);

    return 0;
}

私はOSX Lion(ver 1.7.3、llvm-gcc 4.2.1)とCentOS 6.2でSIGSEGVを手に入れました。私はここで間違って何をしていますか?ありがとう

7
宣言されていない変数を使用しています。しかし、これはsegfaultではなく、コンパイルエラーを生成するはずです。しかし、 i を宣言すると、segfault、gcc-4.5.1、openSuSE 11.4も得られます。
追加された 著者 Daniel Fischer,
Win7/cygwin、gcc 4.5.0と同じです。私はgdbで実行しました。スレッドを作成してから、 Program received signal SIGSEGV、Segmentation faultを取得します。 omp_get_max_active_levels()内の0x63602726 while(1)なしで正常に動作します。 OpenMPは無限ループをどのように扱っていますか?
追加された 著者 Steve Blackwell,
私はintを追加するのを忘れていた..私は急いでコードを書いた:D。
追加された 著者 sfa,

3 答え

Not sure if this is relevant to the compiler version and configuration but while(true){} terminates

より正確には、

  • ライブラリI/O関数を呼び出しません。
  • 揮発性オブジェクトにアクセスしたり変更したりすることはありません。
  • 同期操作(1.10)またはアトミック操作(29節)を実行しない

終了しない場合は、未定義の動作があります。

これはあなたの状況には当てはまらないかもしれませんが、C ++ 11がより確立されるにつれて、注意してください。

2
追加された
興味深いことに、私はCがそのような定型表現ではないことを認識していませんでした。スタンダードを教えてください。
追加された 著者 spraff,
これはCとは無関係で、制御式が定数式でないの場合にのみ、ループは終了すると見なすことができます。 while(1); は定数式によって制御されるため、ループは終了してはなりません。
追加された 著者 Daniel Fischer,
6.8.5(6)で、「制御式が定数式ではなく、入出力操作を実行しない反復文」という実際の標準がないため、n1570を使用しています。 '定数式ではない'修飾子がもう一度削除された可能性はありますが、後で段落に追加されるため、私はそれを期待しません。
追加された 著者 Daniel Fischer,
こんにちは、私はC =>で未定義の動作は表示されませんwhile(1); (Cの標準を指してください)。それは、それ自身のアドレスでジャンプする無条件ジャンプ(jmp)でなければなりません。私は4スレッド(pthread_create)を作成し、私は開始関数に入れて "while(1);"私はSIGSEGVを取得せず、私の4つのコアは100%です。私はopenmpで同じ動作をしたいと思っていましたが、思ったほど信頼できるものではないようです。
追加された 著者 sfa,

とても興味深い。

コードを少し変更しました そう

int main(void)
{
int i;
#pragma omp parallel 
  {
        while(1);
    }
    return 0;
} 

など

inline void func() {
    while (1) ;
}

int main(void)
{
int i;
#pragma omp parallel for 
    for(i=0;i<8;i++) {
        func();
    }
    return 0;
}

そして彼らはどちらもOKでした。

1
追加された
最適化を有効にしてコンパイルすると、 func()の場合もsegfaultが得られます。
追加された 著者 jfs,
gcc 4.6.1: -O0 なしsegfault、 -O1 + - segfault。
追加された 著者 jfs,
@JF.Sebastianここでは、 func()で、390 +%CPU、-O0から-O3、-Osで何もしません。 Segfaultsは、すべての最適化レベルでは、 while(1); で飾られていません。 gccは4.5.1である。非常に奇妙な。
追加された 著者 Daniel Fischer,
@ SF、私は本当に何が起こるか知りません。生成されたアセンブラコードを見てください。後期私はインテルC ++コンパイラを使用しようとしますが、今は時間がありません。
追加された 著者 mikithskegg,
私はインテルC ++ Composer 12.1でコンパイルを試みましたが、すべて正常に動作します!
追加された 著者 mikithskegg,
私は知っている、私はまた後者を試してみました。 (インラインなしでも動作します)。しかし、私が書いたコードには何が間違っていると思いますか?私のCentOSでは、=> chunk_size = 140737488347560、istart = 0x7fffffffe1b0、iend = 0xcaのようなパラメータでgomp_loop_static_start()が呼び出されます。最後のものは逆参照されるポインタです。したがって、SIGSEGVを取得します。私が明示的にschedule()を使用してチャンクサイズを値に設定した場合、iendポインタは有効なアドレスです。SIG 11も取得しません。また、インラインfncで後者のコードをデバッグした場合、gomp_loop_static_start()まったく呼ばれる。
追加された 著者 sfa,
感謝mikithskegg、問題はgccにあった。
追加された 著者 sfa,

There was a bug in the gcc regarding this issue, I reported it and they will provide a fix. Here is the link: GCC bug

1
追加された