如何将 2 个 16 位向量相乘并将结果存储在 SSE 中的 32 位向量中
How to Multiply 2 16 bit vectors and store result in 32 bit vector in sse?
我需要将 2 个 16 位向量相乘,并且由于溢出问题,我想获得 32 位向量的输出,如下所示。
A = [ 1, 2, 3, 4, 5, 6, 7, 8]
B = [ 1, 3, 5, 6, 8, 9, 10 ,12 ]
C1= [ 1*1 + 2*3, 3*5, 4*6]
c2= [ 5*8, 6* 9, 7*10, 8*12 ]
我能够通过首先将 A 和 B 分成 32 位向量,然后使用下面的乘法函数来做到这一点
static inline __m128i muly(const __m128i &a, const __m128i &b)
{
__m128i tmp1 = _mm_mul_epu32(a, b); /* mul 2,0*/
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a, 4), _mm_srli_si128(b, 4)); /* mul 3,1 */
return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0))); /* shuffle results to [63..0] and pack */
}
但我认为这是没有效率的,我们可以利用_mm_mullo_epi16
来提高效率。有人可以建议/发布代码来实现这一点吗?
是的,你可以这样做:
static inline void muly(__m128i &vh, __m128i &vl, // output - 2x4xint32_t
const __m128i v0, const __m128i v1) // input - 2x8xint16_t
const __m128i vhi = _mm_mulhi_epi16(v0, v1); // mul lo
const __m128i vlo = _mm_mullo_epi16(v0, v1); // mul hi
vh = _mm_unpackhi_epi16(vlo, vhi); // interleave results
vl = _mm_unpacklo_epi16(vlo, vhi);
}
请注意,对于 16x16 乘法,您可能需要考虑不动点乘法。这种方法通常用于DSP和图像处理任务,如滤波。它比完整的 16x16->32 乘法效率高得多,并且还避免了数据扩展和缩减到 16 位的需要。
请参阅:__m128i _mm_mulhrs_epi16 (__m128i a, __m128i b)
相关文章:
- 访问存储在向量C++中的结构的多态成员
- 添加存储在向量中的大整数的函数出现问题
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 如何从用户那里获取输入并将其存储在向量中?
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 在二维向量或数组中可以存储的最大元素数是多少?
- 存储在堆分配向量中的指针的免费存储
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- Sqlite3:将数据库表名存储在向量中
- 如何在数组和向量 c++ 中存储和保存输入
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 代码将向量存储为向量<vector>,为什么没有错误消息?
- 替代STD ::向量存储参考而不是对象的副本
- 将向量存储在<file> CStringArray 中?
- 将可变大小结构的向量存储在c++中的二进制文件中
- 使用向量c++存储和洗牌一副牌
- 将指针向量存储在文件中并再次读取它们
- 是否可以/建议将向量存储在结构中?C++