为什么C ++标准库中没有SIMD功能?

时间:2019-12-17 12:03:39

标签: c++ stl simd

SSE自1999年以来一直存在,它及其后续扩展是提高C ++程序性能的最强大工具之一。但是,没有标准化的容器/算法等明确使用此容器(我知道吗?)。是否有一个原因?有没有从未通过的提案?

1 个答案:

答案 0 :(得分:3)

(parallelism TS v2) 中有对映射到常见 ISA 的 SIMD 扩展的显式短向量 SIMD 类型的实验支持,但截至 2021 年 8 月,只有 GCC 实现了它。该提案背后的想法是在博士项目期间开发的(2015 thesis here)。 GCC 实现 wrote an article 的作者将现有的 SSE 字符串处理算法转换为使用其库的 2019 年迭代,实现了类似的性能和更高的可读性。下面是一些使用它和生成的程序集的更简单的代码:

乘加

#include <experimental/simd> // Fails on MSVC 19 and others
using vec4f = std::experimental::fixed_size_simd<float,4>;

void madd(vec4f& out, const vec4f& a, const vec4f& b)
{
    out += a * b;
}

使用 -march=znver2 -Ofast -ffast-math 进行编译,我们确实得到了为此生成的硬件融合乘加:

madd(std::experimental::parallelism_v2::simd<float, std::experimental::parallelism_v2::simd_abi::_Fixed<4> >&, std::experimental::parallelism_v2::simd<float, std::experimental::parallelism_v2::simd_abi::_Fixed<4> > const&, std::experimental::parallelism_v2::simd<float, std::experimental::parallelism_v2::simd_abi::_Fixed<4> > const&):
        vmovaps xmm0, XMMWORD PTR [rdx]
        vmovaps xmm1, XMMWORD PTR [rdi]
        vfmadd132ps     xmm0, xmm1, XMMWORD PTR [rsi]
        vmovaps XMMWORD PTR [rdi], xmm0
        ret

点积

点/内积可以简洁地写成:

float dot_product(const vec4f a, const vec4f b)
{
    return reduce(a * b);
}

-Ofast -ffast-math -march=znver2

dot_product(std::experimental::parallelism_v2::simd<float, std::experimental::parallelism_v2::simd_abi::_Fixed<4> >, std::experimental::parallelism_v2::simd<float, std::experimental::parallelism_v2::simd_abi::_Fixed<4> >):
        vmovaps xmm1, XMMWORD PTR [rsi]
        vmulps  xmm1, xmm1, XMMWORD PTR [rdi]
        vpermilps       xmm0, xmm1, 27
        vaddps  xmm0, xmm0, xmm1
        vpermilpd       xmm1, xmm0, 3
        vaddps  xmm0, xmm0, xmm1
        ret

(Godbolt link with some more playing around).