c++ simd编程

2023-01-29  本文已影响0人  谭英智

[toc]

简介

simd编程利用cpu的向量化部件,通过在同一时间对数组的多个元素进行同时计算,来加快计算速度。

增速的幅度一般要看cpu的向量化寄存器可以容纳多少个数据元素

例如如果可以同时容纳8个整数,那么通过simd,理想的增速将是原来的8倍

概念性simd算法

transfer

transfer可以理解为y=f(x)的问题

x通过f函数的转换变成了y

是一对一的转换

simd-transfer

DR3 simd库的代码如下:

std::vector<FloatType> c(SZ, VecXX::SCALA_TYPE(0.5));
VecXX test(v);
auto squareLambda = [](const auto&& rhs) { return rhs*rhs; };
auto res = transform(squareLambda, test);

reduce

reduce可以理解为z = f(x, y);

两个转一个的问题

例如在计算数组最大值时可以使用reduce来不断的减少可选集合

simd-reduce

DR3代码如下:
计算最小值

auto minDbl = [](auto lhs, auto rhs) { return return lhs < rhs ? lhs : rhs; };

auto minRes = reduce(test, minDbl);

select

select可以理解为 z = f(x, y, mask);

通过mask来过滤x和y,并把结果合并成z,返回

simd-select

simd库的现状

c++ simd库目前有很多

例如

然而这些库没有被工业界广泛使用,更多是处于萌芽阶段,并不成熟

一般,如果c++要使用simd技术来优化代码

很可能是通过裸用AVX之类的库来实现

SIMD原生API介绍

数据类型

16 bytes 32 bytes
32-bit float __m128 __m256
64-bit float __128d __m256d
Int __128i __m256i

API

void mul4_vectorized( float* ptr )
{
    __m128 f = _mm_loadu_ps( ptr );
    f = _mm_mul_ps( f, f );
    _mm_storeu_ps( ptr, f );
}

shuffle:

z = f(x, y);

simd-movehl

z = f(x, y);

simd-movelh

z = f(x, y);

simd-unpacklo

z = f(x, y);

simd-unpackhi

z = f(x);

simd-movehdup

z = f(x);

simd-moveldup

z = f(x)

simd-broad

z = f(x, y, mask)

各取两个

simd-shuffle

z = f(x, y, mask)

simd-blend

z = f(x, y, mask)

simd-insert
上一篇 下一篇

猜你喜欢

热点阅读