(parallelism TS v2) 中对显式短向量 SIMD 类型提供实验性支持,这些类型映射到常见 ISA 的 SIMD 扩展,但截至 2021 年 8 月只有 GCC 实现它。上面链接的 Cppreference 文档不完整,但还有其他Working Draft, Technical Specification for C++ Extensions for Parallelism, Document N4808 中涵盖的详细信息。该提案背后的想法是在博士项目 (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)。