美文网首页
c++ simd编程

c++ simd编程

作者: 谭英智 | 来源:发表于2023-01-29 00:47 被阅读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库目前有很多

例如

  • boost simd
  • std::simd
  • VCL
  • DR3

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

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

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

SIMD原生API介绍

数据类型

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

API

  • mm_loadu_ps : 初始化,加载数据
  • _mm_storeu_ps : 写回数据
  • _mm_mul_ps : 相乘操作
void mul4_vectorized( float* ptr )
{
    __m128 f = _mm_loadu_ps( ptr );
    f = _mm_mul_ps( f, f );
    _mm_storeu_ps( ptr, f );
}

  • _mm_add_ps : 相加操作
  • _mm_setzero_ps : 初始0向量
  • _mm_xor_si128 : 亦或
  • _mm_cmpeq_epi32 : 是否相等
  • _mm_min_ss :获取最小值
  • _mm_max_sd :获取最大
  • _mm_rcp_ps :x分之一
  • _mm_rsqrt_ps : x根号分之一
  • _mm_hadd_ps : [a, b, c, d] and [e, f, g, h] => [a+b, c+d, e+f, g+h]
  • _mm_addsub_ps : [a, b, c, d] and [e, f, g, h] => [a-e, b+f, c-g, d+h]
  • _mm_round_ps
  • _mm_ceil_ps

shuffle:

  • _mm_movehl_ps

z = f(x, y);

simd-movehl
  • _mm_movelh_ps

z = f(x, y);

simd-movelh
  • _mm_unpacklo_ps

z = f(x, y);

simd-unpacklo
  • _mm_unpackhi_ps

z = f(x, y);

simd-unpackhi
  • _mm_movehdup_ps

z = f(x);

simd-movehdup
  • _mm_moveldup_ps

z = f(x);

simd-moveldup
  • _mm_broadcastss_ps

z = f(x)

simd-broad
  • _mm_shuffle_ps

z = f(x, y, mask)

各取两个

simd-shuffle
  • _mm_blend_ps

z = f(x, y, mask)

simd-blend
  • _mm_insert_ps

z = f(x, y, mask)

simd-insert
  • _mm_permute_ps

相关文章

网友评论

      本文标题:c++ simd编程

      本文链接:https://www.haomeiwen.com/subject/veiuhdtx.html