int8 数组与标量的快速乘法
fast multiplication of int8 arrays by scalars
我想知道是否有一种快速乘以 int8
数组的方法,即
for(i = 0; i < n; ++i)
z[i] = x * y[i];
我看到 Intel intrinsics guide 列出了几个 SIMD 指令,例如 _mm_mulhi_epi16
和 _mm_mullo_epi16
对 int16
执行类似的操作。我是否缺少 int8
的类似内容?
把输入分成low & hi,一个就可以
__m128i const kff00ff00 = _mm_set1_epi32(0xff00ff00);
__m128i lo = _mm_mullo_epi16(y, x);
__m128i hi = _mm_mullo_epi16(_mm_and_si128(y, kff00ff00), x);
__m128i z = _mm_blendv_epi8(lo, hi, kff00ff00);
AFAIK,YYyy|YYyy|YYyy|YYyy
的高位 YY
乘以 00xx|00xx|00xx|00xx
不会干扰低 8 位 ??ll
,同样 YY00|YY00
* 00xx|00xx
在 HH00
处生成正确的 8 位产品。这两个正确对齐的结果需要混合。
__m128i x = _mm_set1_epi16(scalar_x);
和 __m128i y = _mm_loadu_si128(...);
另一种方法是使用 shufb
计算 LutLo[y & 15] + LutHi[y >> 4]
,不幸的是,转换也必须由 _mm_and_si128(_mm_srli_epi16(y,4),_mm_set1_epi8(15))
模拟。
我想知道是否有一种快速乘以 int8
数组的方法,即
for(i = 0; i < n; ++i)
z[i] = x * y[i];
我看到 Intel intrinsics guide 列出了几个 SIMD 指令,例如 _mm_mulhi_epi16
和 _mm_mullo_epi16
对 int16
执行类似的操作。我是否缺少 int8
的类似内容?
把输入分成low & hi,一个就可以
__m128i const kff00ff00 = _mm_set1_epi32(0xff00ff00);
__m128i lo = _mm_mullo_epi16(y, x);
__m128i hi = _mm_mullo_epi16(_mm_and_si128(y, kff00ff00), x);
__m128i z = _mm_blendv_epi8(lo, hi, kff00ff00);
AFAIK,YYyy|YYyy|YYyy|YYyy
的高位 YY
乘以 00xx|00xx|00xx|00xx
不会干扰低 8 位 ??ll
,同样 YY00|YY00
* 00xx|00xx
在 HH00
处生成正确的 8 位产品。这两个正确对齐的结果需要混合。
__m128i x = _mm_set1_epi16(scalar_x);
和 __m128i y = _mm_loadu_si128(...);
另一种方法是使用 shufb
计算 LutLo[y & 15] + LutHi[y >> 4]
,不幸的是,转换也必须由 _mm_and_si128(_mm_srli_epi16(y,4),_mm_set1_epi8(15))
模拟。