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

ima*_*ett 11 c++ vectorization visual-c++

这是一个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;
}
Run Code Online (Sandbox Code Playgroud)

编译时,MSVC 2013通知我(/Qvec-report:2)

main.cpp(11):info C5002:由于'1200'原因,循环未向量化

这意味着"[l] oop包含循环携带的数据依赖性".

我注意到,对构造函数或析构函数进行注释Vec(编辑:或者默认它们,例如Vec()=default;)会导致它成功进行向量化.我的问题:为什么?


注意:切换#if意志也会使它工作.这__restrict很重要.
注意:更改float const& scalarfloat const scalar导致向量化报告1303(向量化不会是一个胜利),我怀疑因为引用可以直接传递到SSE寄存器,而pass-by-value需要另一个副本.

Ale*_* F. 1

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

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

要么定义一个复制构造函数,要么根本不定义空构造函数和析构函数。