診断 15304: ループ はベクトル化されませんでした: マルチバージョンのベクトル化できないループ・インスタンスです。

同カテゴリーの次の記事

リマーク #15319: ループ はベクトル化されませんでした: novector ディレクティブが使用されています。

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Diagnostic 15304: loop was not vectorized: non-vectorizable loop instance from multiversioning」の日本語参考訳です。


このベクトル診断メッセージは、インテル® C++ コンパイラー 15.0 以降で生成されます。

原因:

この診断メッセージは、コンパイラーが単一のループバ―ションを生成するのに必要な十分な情報をコードから得られなかった場合に出力されます。以下にこのシナリオの例を示します。この例では、コンパイラーはメモリーのエイリアシング (ポインターがメモリー上のオーバーラップする場所を指す) を想定して、保守的な観点からベクトルバージョンと非ベクトルバージョンの 2 つのループを生成します。

例:

void foo(float *a, float *b, float *c){
    for(int i = 0 ; i < 256; i++)
        c[i] = a[i] * b[i];
    return;
    }

$ icl 15304.c /c /Qopt-report:2 /Qopt-report-phase:vec

以下の診断メッセージは、インテル® C++ コンパイラー for Windows* 19.1.0.166 (ビルド 20191121) で生成しました。

最適化レポート開始: foo(float *, float *, float *)

    レポート: ベクトルの最適化 [vec]

ループの開始 D:\15304.c(3,5)
<ベクトル化のピールループ, マルチバージョン v1>
ループの終了

ループの開始 D:\15304.c(3,5)
<マルチバージョン v1>
   リマーク #15300: ループがベクトル化されました。
   リマーク #15442: すべてのループは剰余ループとして実行されます。
   リマーク #15448: マスクなしアライン・ユニット・ストライド・ロード: 1
   リマーク #15449: マスクなしアライン・ユニット・ストライド・ストア: 1
   リマーク #15450: マスクなし非アライン・ユニット・ストライド・ロード: 1
   リマーク #15475: --- ベクトルのコストサマリー開始 ---
   リマーク #15476: スカラーのコスト: 8
   リマーク #15477: ベクトルのコスト: 1.750
   リマーク #15478: スピードアップの期待値: 3.970
   リマーク #15488: --- ベクトルのコストサマリー終了 ---
    ループの終了

ループの終了

ループの開始 D:\15304.c(3,5)
<代替アライメントでベクトル化されたループ, マルチバージョン v1>
ループの終了

ループの開始 D:\15304.c(3,5)
<ベクトル化の剰余ループ, マルチバージョン v1>
ループの終了

ループの開始 D:\15304.c(3,5)
<マルチバージョン v2>
   リマーク #15304: ループ はベクトル化されませんでした: マルチバージョンのベクトル化できないループ・インスタンスです。
ループの終了

解決方法:

開発者がメモリーにエイリアシングがないことに確信がある場合は、__restrict__ キーワードを使用して、引数として渡されたポインターがメモリー上でオーバーラップしないことを明示します。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事