自1999年起,SSE和其后续扩展已成为提高C++程序性能最强有力的工具之一。然而,就我所知,没有标准化的容器、算法等明确利用它们的(是这样吗?)。这是有原因的吗?是否存在过未通过的提案?
#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
gcc -O2
不包括自动向量化,因此使用SIMD的证明是它用__attribute__((vector_size(16)))
定义。但是,https://godbolt.org/z/79KddEdba表明,即使在C中按值传递,它也不会像普通的`__m128`非类typedef那样通过xmm寄存器传递,在x86-64 System V ABI中,甚至返回它需要使用指针:(幸运的是,在内联之后这并不重要,但通常不想通过引用传递SIMD向量。 - Peter Cordes[[gnu::always_inline]]
,以启用具有不同-m
标志的TUs的准ODR兼容链接。”):http://gcc.1065356.n8.nabble.com/PATCH-1-2-Add-std-experimental-simd-from-the-Parallelism-TS-2-td1807958.html - ahcox
std::execution
策略?<algorithm>
库中的大多数算法都可以使用它们。 - Yksisarvinen