为什么这个自动矢量化器关心构造函数/析构函数?

时间:2015-05-15 22:49:16

标签: c++ visual-c++ vectorization

这是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寄存器中传值需要另一份副本。

1 个答案:

答案 0 :(得分:1)

为什么使用空的默认构造函数inline ~Vec(void) {}声明一个空的非虚拟析构函数inline Vec(void) {}

因此,编译器不会生成默认的复制构造函数。因此,没有它就无法编译代码return result;,因为这需要将结果复制到临时返回的对象中(可能不是您想要的)。

定义复制构造函数,或者根本不定义空构造函数和析构函数。