[英]vc++ no longer vectorize simple for loops with range-based syntax
在用基於范圍的循環替換我的許多“舊”for循環之前,我使用visual studio 2013進行了一些測試:
std::vector<int> numbers;
for (int i = 0; i < 50; ++i) numbers.push_back(i);
int sum = 0;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) sum += *number;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//vectorization
for (auto __begin = numbers.begin(),
__end = numbers.end();
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//no vectorization :(
for (auto number : numbers) sum += number;
//no vectorization :(
for (auto& number : numbers) sum += number;
//no vectorization :(
for (const auto& number : numbers) sum += number;
//no vectorization :(
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
看看反匯編,循環的標准都是矢量化的:
00BFE9B0 vpaddd xmm1,xmm1,xmmword ptr [eax]
00BFE9B4 add ecx,4
00BFE9B7 add eax,10h
00BFE9BA cmp ecx,edx
00BFE9BC jne main+140h (0BFE9B0h)
但基於循環的范圍不是:
00BFEAC6 add esi,dword ptr [eax]
00BFEAC8 lea eax,[eax+4]
00BFEACB inc ecx
00BFEACC cmp ecx,edi
00BFEACE jne main+256h (0BFEAC6h)
有沒有理由為什么編譯器無法對這些循環進行矢量化?
我真的很想使用新的語法,但是失去矢量化太糟糕了。
我剛剛看到這個問題 ,所以我嘗試了/Qvec-report:2
標志,給出了另一個原因:
loop not vectorized due to reason '1200'
那是:
循環包含阻止矢量化的循環攜帶數據依賴性。 循環的不同迭代相互干擾,使得對循環進行矢量化將產生錯誤的答案,並且自動矢量化器不能向自身證明不存在這樣的數據依賴性。
這是同一個bug嗎? (我也試過最后一個vc ++編譯器“2013年11月CTP”)
我應該在MS連接上報告嗎?
對於評論,我使用原始int數組而不是向量進行相同的測試,因此不涉及迭代器類,只是原始指針。
現在除了兩個“基於模擬范圍的”循環外,所有循環都被矢量化。
編譯說這是由於'501'的原因:
歸納變量不是本地的; 或上限不是循環不變的。
我不知道發生了什么......
const size_t size = 50;
int numbers[size];
for (size_t i = 0; i < size; ++i) numbers[i] = i;
int sum = 0;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) sum += *number;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//vectorization ?!
for (auto number : numbers) sum += number;
//vectorization ?!
for (auto& number : numbers) sum += number;
//vectorization ?!
for (const auto& number : numbers) sum += number;
//vectorization ?!
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
我的猜測可能是基於范圍的for循環不會隨意知道對象是向量或數組或鏈表,因此編譯器事先不知道向量化循環。 基於范圍的for循環相當於其他語言中的foreach循環。 可能有一種方法可以提示編譯器使用宏或編譯指示或編譯器設置預先對循環進行矢量化。 要檢查請嘗試使用其他編譯器中的代碼,看看你得到了什么,如果你得到其他編譯器的非矢量化匯編代碼,我不會感到驚訝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.