6

我有一个看起来像这样的工会

 union bareVec8f { 
    __m256 m256; //avx 8x float vector
    float floats[8];
    int ints[8];
    inline bareVec8f(){
    }
    inline bareVec8f(__m256 vec){
        this->m256 = vec;
    }
    inline bareVec8f &operator=(__m256 m256) {
        this->m256 = m256;
        return *this;
    }

    inline operator __m256 &() {
        return m256;
    }
}

__m256 需要在 32 字节边界上对齐才能与 SSE 函数一起使用,并且应该自动对齐,即使在联合内也是如此。

当我这样做时

bareVec8f test = _mm256_set1_ps(1.0f);

我得到一个分段错误。由于我制作的构造函数,这段代码应该可以工作。但是,当我这样做时

bareVec8f test;
test.m256 = _mm256_set1_ps(8.f);

我没有得到分段错误。

因此,因为工作正常,联合可能正确对齐,似乎构造函数导致了一些分段错误

我正在使用 gcc 64 位 windows 编译器

---------------------------------编辑马特设法产生了似乎在这里发生的错误的最简单示例.

#include <immintrin.h>

void foo(__m256 x) {}

int main()
{
    __m256 r = _mm256_set1_ps(0.0f);
    foo(r);
}

我正在编译 -std=c++11 -mavx

4

1 回答 1

7

这是 Windows 的 g++ 中的一个错误。它不应该执行 32 字节堆栈对齐。 错误 49001 错误 54412


这个 SO 线程上,有人制作了一个 Python 脚本来处理 g++ 的程序集输出以解决问题,因此这是一种选择。

否则,为了在您的联合中避免这种情况,您可以使__m256按值获取的函数改为通过引用获取。除非优化低/关闭,否则这不应该有任何性能损失。

如果您不知道 - 联合别名会导致 C++ 中的未定义行为,例如,不允许先写入然后m256再读取。因此,您的问题可能有不同的解决方案。floatsints

于 2015-06-18T23:50:50.933 回答