simd笔记
simd笔记
1. 语义
1. 绝对值(一元运算)
其实就是将一个X个Y比特的数做一次绝对值运算,比如下面对16个16位有符号数做了16次abs运算,但只有一条指令
__m256i _mm256_abs_epi16(__m256i a)
2. 加减法之类(二元运算)
- 简单理解为a+b就行;
- 还有理解饱和加法(防止溢出)的指令就OK,其实就是溢出了取最大值
3. 位运算(二元运算)
类似and,or,也有组合运算,比如andnot,这里区分是针对谁做not就行
4. 混合操作
其实有点像选择器,输入两个向量和一个mask,然后根据mask来选择,这里有些api非常迷惑,因为mask是8bit的,然后avx256可能会拆分成两个128bit然后执行两次
__m256i _mm256_blend_epi16 (__m256i a, __m256i b, const int imm8)
比如这里,实际上对于a和b来说,他们是16个16bit的整数,但imm8只有8bit,所以语义上
相当于__mm128_blend_epi16(_m128i a, __m128i b, const int imm8)
执行两次
这里的执行逻辑是:
根据mask,如果某个bit为1,则选择左边的a(8*16位)对应的元素,否则选择b
5. 广播指令
有点像python的'a' * 16
的感觉,其实就是针对某个元素快速复制或者扩展N份
__m256i _mm256_broadcastw_epi16 (__m128i a)
将低16位扩展16个位置
6. 数据加载和存储指令(其实就是输入输出)
内存数据加载到向量寄存器或者将向量寄存器的值写入到内存中,有区分内存地址对齐的版本和不对齐的版本;还有带mask的加载,只加载特定的数据,注意这里的mask其实是128位向量,然后用最高位来决定是否加载(这个向量一般来自于比较指令)
__m128d _mm_loadu_pd (double const* mem_addr)
7. 比较与测试指令
这里需要注意新接口,有些api是有mask的
8. 置换与指令重排(Swizzle类指令)
调整向量中元素的顺序,支持固定模式或动态索引重排,常用于数据格式转换、矩阵转置,比如图像通道分离、合并(rgb <-> bgr)、行列重排、数据对齐调整。
//
//
//
reference
- intel simd指令