VS2012のC++コンパイラで自動ベクトル化できない理由について私が見ていない以下のループコードについて明らかなことを誰かが見ていますか?
コンパイラが私に与えるのは、コマンドラインスイッチinfo C5002: loop not vectorized due to reason '1200'
を使用するときだけです。/Qvec-report:2
Reason 1200は、MSDNで次のように文書化されています。
ループには、ベクトル化を妨げるループで運ばれるデータ依存関係が含まれています。ループの異なる反復は互いに干渉し合うため、ループをベクトル化すると間違った答えが生成され、自動ベクトル化機能はそのようなデータ依存性がないことを証明できません。
ループで運ばれるデータの依存関係がないことは知っていますが(またはかなり確信しています)、コンパイラーがこれを実現するのを妨げている原因はわかりません。
これらsource
とdest
ポインタは同じメモリをオーバーラップしたりエイリアスしたりすることはなく、コンパイラにそのヒントを提供しようとしてい__restrict
ます。
pitch
4096
これは8bpp->32bppのレンダリング/変換関数であり、列ごとに動作するため、画面の解像度に応じて、は常に正の整数値になります。
byte * __restrict source;
DWORD * __restrict dest;
int pitch;
for (int i = 0; i < count; ++i) {
dest[(i*2*pitch)+0] = (source[(i*8)+0]);
dest[(i*2*pitch)+1] = (source[(i*8)+1]);
dest[(i*2*pitch)+2] = (source[(i*8)+2]);
dest[(i*2*pitch)+3] = (source[(i*8)+3]);
dest[((i*2+1)*pitch)+0] = (source[(i*8)+4]);
dest[((i*2+1)*pitch)+1] = (source[(i*8)+5]);
dest[((i*2+1)*pitch)+2] = (source[(i*8)+6]);
dest[((i*2+1)*pitch)+3] = (source[(i*8)+7]);
}
それぞれの周りのsource[]
親は、最も単純な形式で、関数呼び出しなしではループが自動ベクトル化されないため、ここで省略した関数呼び出しの残骸です。
編集:
ループを単純化して、次のような最も簡単な形式にしました。
for (int i = 0; i < 200; ++i) {
dest[(i*2*4096)+0] = (source[(i*8)+0]);
}
これでも、同じ1200理由コードが生成されます。
編集(2):
ローカル割り当てと同一のポインタータイプを使用したこの最小限のテストケースでも、自動ベクトル化に失敗します。私はこの時点で単に困惑しています。
const byte * __restrict source;
byte * __restrict dest;
source = (const byte * __restrict ) new byte[1600];
dest = (byte * __restrict ) new byte[1600];
for (int i = 0; i < 200; ++i) {
dest[(i*2*4096)+0] = (source[(i*8)+0]);
}