std::AVX内部函数数组

std::array of AVX intrinsics

本文关键字:数组 内部函数 AVX std      更新时间:2023-10-16

我不知道我对AVX内部函数如何与std::array一起工作的理解是否有所欠缺,但当我将两者结合在一起时,我对Clang有一个奇怪的问题。

样本代码:

std::array<__m256, 1> gen_data()
{
    std::array<__m256, 1> res;
    res[0] = _mm256_set1_ps(1);
    return res;
}
void main()
{
    auto v = gen_data();
    float a[8];
    _mm256_storeu_ps(a, v[0]);
    for(size_t i = 0; i < 8; ++i)
    {
        std::cout << a[i] << std::endl;
    }
}

Clang 3.5.0的输出(上4个浮点为垃圾数据):

11.1.1.8.82272e-3905.88148e-390

GCC 4.8.2/4.9.1的输出(预期):

11.1.1.1.1.1.1

如果我将v作为输出参数传递给gen_data,那么它在两个编译器上都可以正常工作。我愿意接受这可能是Clang中的一个错误,但我不知道这是否是未定义的行为(UB)。Clang 3.7*(svn构建)和Clang的测试现在似乎给出了我预期的结果。如果我切换到SSE 128位内部函数(__m128),那么所有编译器都会给出相同的预期结果。

所以我的问题是:

  1. 这里有UB吗?或者这只是Clang 3.5.0中的一个错误
  2. 我对__m256只是一个32字节对齐的内存块的理解正确吗?或者它还有什么特别的地方需要我小心吗

这看起来像是clang错误,现在已经修复,我们可以从这个错误报告中看到这一点,它演示了使用常规数组时的一个非常相似的问题。

假设std::array实现类似于以下内容的存储:

T elems[N];

CCD_ 6和CCD_。其中一条评论说:

然而,libc++的std::array<__m256i, 1>在任何优化级别上都不起作用。

错误报告实际上是基于这个SO问题:用__m256值的数组生成错误的代码是clang错误吗?这是非常相似的,但是处理规则数组的情况。

错误报告包含一个可能的解决方案,OP表示这就足够了:

在我的实际代码中,num_vectors是基于simd_pack类型的一些C++模板参数计算的。在许多情况下,这是1,但它也经常大于1。不过,你的观察给了我一个想法;我可以尝试引入一个模板专门化来捕捉num_vectors == 1的情况。它可以只使用一个__m256成员,而不是大小为1的数组。我得检查一下这有多可行。