診断 15517: インライン・アセンブリーで EBX/RBX レジスターが使用されているため、このサブルーチンのループはベクトル化できません。

同カテゴリーの次の記事

診断 15521: ループはベクトル化されませんでした: ループ制御変数が識別されませんでした。ループを実行する前に反復数を計算できる式に置き換えてください。

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Diagnostic 15517: loops in this subroutine cannot be vectorized due to use of EBX/RBX register in inline ASM」の日本語参考訳です。


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

原因:

この診断メッセージは、関数が EBX/RBX レジスターを変更すると出力されます。ベクトル化にはアライメントされたスタックフレームが必要です。XMM は 16 バイト、YMM は 32 バイト、ZMM は 64 バイトにアライメントする必要があります。インライン・アセンブリーで EBX/RBX レジスターが使用されると、スタックフレームをアライメントできなくなり、ベクトル化されません。

例:

void foo(int *A, int *B, int n){
    int i;
    __asm {
        push rbx
        mov ebx, eax
    }
    for (i=0;i<n;i++){
        B[i] += A[i];
    }
    __asm {
        pop rbx
    }
}

$ icl 15517.c /c /O2 /Qopt-report:2 /Qopt-report-phase:vec /QxAVX
(Linux* では -fasm-blocks を指定)

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

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

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

リマーク #15517: インライン・アセンブリーで EBX/RBX レジスターが使用されているため、このサブルーチンのループはベクトル化できません。[ D:\15517.c(1,32) ]

ループの開始 D:\15517.c(7,3)
<マルチバージョン v1>
ループの終了

ループの開始 D:\15517.c(7,3)
<剰余, マルチバージョン v1>
ループの終了

ループの開始 D:\15517.c(7,3)
<マルチバージョン v2>
ループの終了

ループの開始 D:\15517.c(7,3)
<剰余, マルチバージョン v2>
ループの終了

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

関連記事