インテル® C++ コンパイラー 17.0 デベロッパー・ガイドおよびリファレンス
ループの上限式 (%s) の値を一時ローカル変数に格納して、この変数をループの上限式として使用します (行 %d のループ)。 これは、ループの直前に "temp = %s" 形式の文を挿入し、ループの上限式を "temp" に置換することで行えます。 一意な名前を選択し、ループのオリジナルの上限式を "temp" に置換します。
ループの実行中に上限が変更されない場合は、ループの上限をローカル変数に格納します。 これにより、コンパイラーがループを適切にカウントされる do ループとして認識し、ベクトル化と並列化を含むさまざまなループの最適化が有効になります。
このメッセージは、コンパイラーが置換される上限の変数を正しく出力できる場合に表示されます。
次の例について考えてみます。
typedef struct {
float* data;
} Vector;
typedef struct {
int len;
} NetEnv;
// これはベクトル化されません
void
mul(
NetEnv* ne,
Vector* rslt,
Vector* den,
Vector* num)
{
float* r;
float* d;
float* n;
int i;
r = rslt->data;
d = den->data;
n = num->data;
for (i = 0; i < ne->len; ++i) {
r[i] = n[i] * d[i];
}
return;
}
この例では、デフォルトの O2 設定でコンパイラーがこのループをベクトル化できません。
安全であることが分かっている場合は、次のようにプログラムコードを変更します。
typedef struct {
float* data;
} Vector;
typedef struct {
int len;
} NetEnv;
// これはベクトル化されます
void
mul(
NetEnv* ne,
Vector* rslt,
Vector* den,
Vector* num)
{
float* r;
float* d;
float* n;
int i, local_len;
r = rslt->data;
d = den->data;
n = num->data;
local_len = ne->len;
for (i = 0; i < local_len; ++i) {
r[i] = n[i] * d[i];
}
return;
}
ループ全体の実行を通して上限の値が変更されないことを確認してください。