首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vc++不再使用基于范围的语法将简单的for循环矢量化。

vc++不再使用基于范围的语法将简单的for循环矢量化。
EN

Stack Overflow用户
提问于 2014-11-15 01:13:01
回答 1查看 604关注 0票数 10

在用基于范围的for循环替换大量“旧”for循环之前,我在visual studio 2013中运行了一些测试:

代码语言:javascript
复制
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);

从反汇编的角度来看,标准的循环都是矢量化的:

代码语言:javascript
复制
00BFE9B0  vpaddd      xmm1,xmm1,xmmword ptr [eax]  
00BFE9B4  add         ecx,4  
00BFE9B7  add         eax,10h  
00BFE9BA  cmp         ecx,edx  
00BFE9BC  jne         main+140h (0BFE9B0h)  

但基于循环的范围并不是:

代码语言:javascript
复制
00BFEAC6  add         esi,dword ptr [eax]  
00BFEAC8  lea         eax,[eax+4]  
00BFEACB  inc         ecx  
00BFEACC  cmp         ecx,edi  
00BFEACE  jne         main+256h (0BFEAC6h)  

为什么编译器不能向量化这些循环呢?

我真的很想使用新的语法,但是放松矢量化太糟糕了。

我刚刚看到了this question,所以我尝试了/Qvec-report:2标志,给出了另一个原因:

代码语言:javascript
复制
loop not vectorized due to reason '1200'

即:

循环包含循环携带的数据依赖项,以防止矢量化。循环的不同迭代相互干扰,从而使循环矢量化会产生错误的答案,而自动向量器无法向自己证明不存在这种数据依赖。

是同一只虫子吗?(我还尝试了上一个vc++编译器“11月2013年CTP")

我也要在上报告吗?

编辑

对于注释,我对原始int数组而不是向量进行了相同的测试,因此不涉及迭代器类,只涉及原始指针。

现在所有的循环都是矢量化的,除了两个“基于模拟范围的”循环。

编译器说,这是由于“501”的原因:

归纳变量不是局部的,或者上界不是循环不变的.

我不明白发生了什么..。

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

发布于 2015-01-21 23:01:43

我的猜测可能是,基于范围的for循环不会随手知道对象是向量、数组或链接列表,因此编译器事先不知道将循环向量化。在其他语言中,基于范围的for循环等价于foreach循环。可能有一种方法可以提示编译器预先使用宏、务实或编译器设置将循环向量化。若要检查该代码,请尝试在其他编译器中使用该代码,并查看您得到了什么,如果您与其他编译器一起获得非向量化汇编代码,我将不会感到惊讶。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26941410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档