同様の質問がSO for g++に投稿されましたが、これはかなり漠然としていたので、VC++12 / VS2013の具体的な例を投稿して、うまくいけば答えを得られると思いました。
クロスリンク: g++ 、範囲ベースのベクトル化
MSDN は、ベクトル化できるループの例として次を示しています。
for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
( http://msdn.microsoft.com/en-us/library/vstudio/jj658585.aspx )
これは、上記の範囲ベースのアナログ、c スタイルの怪物、および を使用した同様のループの私のバージョンですstd::for_each
。/Qvec-report:2フラグを付けてコンパイルし、コンパイラ メッセージをコメントとして追加しました。
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> vec(1000, 1);
// simple range-based for loop
{
for (int& elem : vec)
{
elem = elem + 1;
}
} // info C5002 : loop not vectorized due to reason '1304'
// c-style iteration
{
int * begin = vec.data();
int * end = begin + vec.size();
for (int* it = begin; it != end; ++it)
{
*it = *it + 1;
}
} // info C5001: loop vectorized
// for_each iteration
{
std::for_each(vec.begin(), vec.end(), [](int& elem)
{
elem = elem + 1;
});
} // (no compiler message provided)
return 0;
}
C スタイルのループのみがベクトル化されます。MSDN ドキュメントによると、理由 1304 は次のとおりです。
1304: ループには、サイズの異なる割り当てが含まれています。
1304 メッセージをトリガーするコードの例として、以下を示します。
void code_1304(int *A, short *B)
{
// Code 1304 is emitted when the compiler detects
// different sized statements in the loop body.
// In this case, there is an 32-bit statement and a
// 16-bit statement.
// In cases like this consider splitting the loop into loops to
// maximize vector register utilization.
for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
B[i] = B[i] + 1;
}
}
私は専門家ではありませんが、関係はわかりません。これは単なるバグレポートですか?実際のプログラムでは、範囲ベースのループがベクトル化されていないことに気付きました。何を与える?
(これがバグのある動作である場合、VS2013 Professional バージョン 12.0.21005.1 REL を実行しています)
編集: 投稿されたバグ レポート: https://connect.microsoft.com/VisualStudio/feedback/details/807826/range-based-for-loops-are-not-vectorized