1. ホーム
  2. c++

OpenMPでは、なぜ!=演算子が使えないのですか?

2023-10-11 08:42:01

疑問点

以下のコードをコンパイルしようとしていました。

#pragma omp parallel shared (j)
{
   #pragma omp for schedule(dynamic)
   for(i = 0; i != j; i++)
   {
      // do something
   }
}

を作成しましたが、以下のエラーが発生しました。 error: invalid controlling predicate .

この OpenMP標準 では parallel for コンストラクタでは、以下の演算子のうち1つだけが許可されています。 < , <= , > >= .

を許可しない根拠が理解できません。 i != j . の場合は理解できるのですが static schedule の場合、コンパイラは各スレッドに割り当てられた反復処理の数を事前に計算する必要があるため、理解することができます。しかし、私はなぜこのようなケースでこの制限を理解することはできません例えば。何か手がかりはありますか?


EDITです。 を作っても for(i = 0; i != 100; i++) とか、"<"とか、"<="とかを入れればよかったのですが、、。

どのように解決するのですか?

.

私はこのテーマについてOpenMPの開発者にメールを送りました、私が得た答えです。

signed intの場合、wrap aroundの動作は未定義です。もし私たちが != を許可すると、プログラマは予期しないトリップカウントを得るかもしれません。問題は、コンパイラがループのトリップカウントを計算するコードを生成できるかどうかです。

のような単純なループの場合。

for( i = 0; i < n; ++i )

の場合、コンパイラは 'n' 回の繰り返しがあると判断することができます。 もしn>=0なら となり、繰り返し回数がゼロの場合は if n < 0 .

のようなループの場合。

for( i = 0; i != n; ++i ) 

も、コンパイラは 'n' 回の繰り返しがあることを判断できるはずです。 if n >= 0 ; if n < 0 のように、何回繰り返したかわからない。

のようなループの場合。

for( i = 0; i < n; i += 2 )

のようにすると、コンパイラはトリップカウント(ループの反復回数)を計算するコードを生成することができます。 floor((n+1)/2) if n >= 0 となり、0 if n < 0 .

のようなループの場合。

for( i = 0; i != n; i += 2 )

の場合、コンパイラは 'i' が 'n' に当たるかどうかを判断できない。もし'n'が奇数だったらどうなるのでしょうか?

のようなループの場合。

for( i = 0; i < n; i += k )

のようにすると、コンパイラはトリップ数を計算するコードを生成することができます。 floor((n+k-1)/k) if n >= 0 となり、0 if n < 0 というのは、コンパイラはループがカウントアップしなければならないことを知っているからです。この場合、もし k < 0 であれば、それは合法的なOpenMPプログラムではありません。

のようなループの場合。

for( i = 0; i != n; i += k )

は、i がカウントアップしているのかダウンしているのかさえ知らない。i'が'n'に当たるかどうかもわからない。無限ループになる可能性があります。

クレジット : OpenMP ARB