这是SSCCE:
class Vec final {
public:
float data[4];
inline Vec(void) {}
inline ~Vec(void) {}
};
Vec operator*(float const& scalar, Vec const& vec) {
Vec result;
#if 1
for (int k=0;k<4;++k) result.data[k]=scalar*vec.data[k];
#else
float const*__restrict src = vec.data;
float *__restrict dst = result.data;
for (int k=0;k<4;++k) dst[k]=scalar*src[k];
#endif
return result;
}
int main(int /*argc*/, char* /*argv*/[]) {
Vec vec;
Vec scaledf = 2.0f * vec;
return 0;
}
编译时,MSVC 2013会通知我(/Qvec-report:2
)
main.cpp(11):info C5002:由于原因导致循环未向量化&#39; 1200&#39;
这意味着&#34; [l] oop包含循环数据依赖&#34;。
我注意到评论Vec
的构造函数或析构函数(编辑:或默认它们,例如Vec()=default;
)会导致它成功进行向量化。我的问题:为什么?
注意:切换#if
也会使其正常工作。 __restrict
很重要
注意:将float const& scalar
更改为float const scalar
会导致向量化报告1303
(向量化不会成为胜利),我怀疑是因为引用可以直接传递到SSE寄存器中传值需要另一份副本。
答案 0 :(得分:1)
为什么使用空的默认构造函数inline ~Vec(void) {}
声明一个空的非虚拟析构函数inline Vec(void) {}
?
因此,编译器不会生成默认的复制构造函数。因此,没有它就无法编译代码return result;
,因为这需要将结果复制到临时返回的对象中(可能不是您想要的)。
定义复制构造函数,或者根本不定义空构造函数和析构函数。