インテル® C++ コンパイラー 17.0 デベロッパー・ガイドおよびリファレンス

GAP メッセージ (診断 ID 30537)

メッセージ

ルーチン "%s" のすべてのポインター型の引数に "restrict" キーワードを追加します。 これにより、行 %d のループに並列化/ベクトル化などの最適化が適用されます。

アドバイス

ファイル全体に適用される -fnoargument-alias (Linux* および OS X*) または /Qno-alias-args (Windows®) の代わりに、このルーチンへのポインター引数に restrict 修飾子を追加できます。 この変更は、キーワードが適用されるルーチンにのみ影響するため、より局所的です。

restrict 修飾子は C 標準の C99 の機能です。この修飾子はデータポインターに適用され、ポインター宣言のスコープ内において、そのポインターによりアクセスされるすべてのデータはほかのポインターによってアクセスされないことを示します。 restrict キーワードは、オブジェクトがほかのポインターによって変更されないという前提に基づいて、コンパイラーによる特定の最適化を有効にします。 restrict 修飾子を持つポインターは意図したとおりに使用されることを確認しなければなりません。 そうでない場合、未定義の動作を引き起こします。

C99 プログラム以外をコンパイルする場合、インテル® コンパイラーでは [Q]restrict も指定する必要があります。

次の例について考えてみます。

void matrix_mul_matrix(int  N, float * C,  float  *A,  float  *B) {
  int  i,j,k;
 
  for (i=0; i<N; i++) {
    for (j=0; j<N; j++) {
      C[i*N+j]=0;
      for(k=0;k<N;k++) {
        C[i*N+j]+=A[i*N+k] * B[k*N+j];
      }
    }
  } 
}

この例では、デフォルト設定の O2 でコンパイラーがループ交換やベクトル化などのループの最適化を適用できません。

安全であることが分かっている場合は、次のようにプログラムコードを変更します。

void matrix_mul_matrix(int  N, float * restrict C,  float  * restrict A,  float
 * restrict B) {
  int  i,j,k;
 
  for (i=0; i<N; i++) {
    for (j=0; j<N; j++) {
      C[i*N+j]=0;
      for(k=0;k<N;k++) {
        C[i*N+j]+=A[i*N+k] * B[k*N+j];
      }
    }
  } 
}

restrict 修飾子を使用する代わりに、コードをコンパイルする前に -fnoargument-alias または /Qno-alias-args を指定することもできます。

確認

"restrict" ポインター修飾子のセマンティクスに沿っていることを確認してください。ルーチンにおいて、そのポインターによりアクセスされるすべてのデータは、ほかのポインターからはアクセスできません。

関連情報