0

C で次のループをベクトル化したい:

for(k = 0; k < SysData->numOfClaGen; k++)
            A[k] = B[k] * cos(x1[2 * k] - x1[ind0 + k]);

ここで、変数間にエイリアスはなくind0、定数です。他のポインタ (AまたはB) はいずれも ind0 を指していないため、ind0ループ全体で一定のままです。

コードを icc でコンパイルすると、ベクトル依存の可能性があるため、このループをベクトル化できないと表示されます。メッセージは次のとおりです。

loop was not vectorized: existence of vector dependence.

問題を絞り込んだところ、ind0 を定数に置き換えると問題が解決することがわかりました。そのため、iccが指し示すA可能性があると考えているind0ため、ind0変更される可能性があると思います。

このようなループをベクトル化しても安全であることをコンパイラーに知らせる方法を知りたいです。

よろしくお願いします。

4

3 に答える 3

2

for ループの前に追加#pragma ivdepすると、想定されるベクトルの依存関係を無視するようにコンパイラに指示します。

#pragma ivdep
for(k = 0; k < SysData->numOfClaGen; k++)
            A[k] = B[k] * cos(x1[2 * k] - x1[ind0 + k]);

ivdep の詳細については、icc docを参照してください。

于 2013-07-27T09:54:16.393 に答える
0

icc は 1 年前に変更され、Linux と Mac のデフォルトとして -ansi-alias が設定されました。Windows の場合、Microsoft の使用法と競合するため、このデフォルトは当てにできません。このオプションは、gcc 3.0 以降のデフォルトである gcc -fstrict-aliasing と同等です。このような限られた問題に対して ivdep restrict または simd を設定するよりも、このオプションを設定する方がはるかに優れていると思います。十分に文書化されていませんが、icc は __restrict を gcc と同じように扱い、それを受け入れるために restrict または C99 オプションを必要としません。原則として、変更されるオブジェクト (上記の例では A[]) に対してのみ機能する必要があります。奇妙なことに、MSVC++ では __restrict の意味が少し異なります。これは、別の方法では可能な依存関係によって妨げられる可能性のある非ベクトル最適化を許可しますが、ベクトル化は有効にしません (ただし、現在のケースには適用される可能性があります)。

于 2015-05-25T13:52:31.413 に答える