x86 - 上证所指令 : Byte+Short

标签 x86 sse instructions

我有很长的字节数组需要添加到类型为 short 的目标数组中(或 int)。
这样的SSE指令存在吗?或者他们的集合?

最佳答案

您需要将每个 8 位值向量解包为两个 16 位值向量,然后将它们相加。

__m128i v = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
__m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0)); // vl = { 7, 6, 5, 4, 3, 2, 1, 0 }
__m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0)); // vh = { 15, 14, 13, 12, 11, 10, 9, 8 }

哪里v是一个包含 16 x 8 位值和 vl 的向量, vh是 8 x 16 位值的两个解压缩向量。

请注意,我假设 8 位值是无符号的,因此当解包为 16 位时,高字节设置为 0(即无符号扩展)。

如果你想对很多这些向量求和并得到一个 32 位的结果,那么一个有用的技巧是使用 _mm_madd_epi16乘数为 1,例如
__m128i vsuml = _mm_set1_epi32(0);
__m128i vsumh = _mm_set1_epi32(0);
__m128i vsum;
int sum;

for (int i = 0; i < N; i += 16)
{
    __m128i v = _mm_load_si128(&x[i]);
    __m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0));
    __m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0));
    vsuml = _mm_add_epi32(vsuml, _mm_madd_epi16(vl, _mm_set1_epi16(1)));
    vsumh = _mm_add_epi32(vsumh, _mm_madd_epi16(vh, _mm_set1_epi16(1)));
}
// do horizontal sum of 4 partial sums and store in scalar int
vsum = _mm_add_epi32(vsuml, vsumh);
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8));
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 4));
sum = _mm_cvtsi128_si32(vsum);

关于x86 - 上证所指令 : Byte+Short,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10637214/

相关文章:

go - Go,x64汇编和CMOVLMI : Where is this opcode described?

performance - 为左打包字节元素生成高效的 sse 洗牌掩码

case 值为reinterpret_cast(string) 的 C++ switch 语句

c++ - SSE 中的条件结构

c - x86_64 上无用的 jp/jnp 汇编指令

linux - 程序集 'Segmentation Fault' 尝试打印十进制数时

使用 SSE SIMD 转换函数

c++ - 由于 SSE 中的内存对齐导致的段错误

arm - MIPS和ARM的区别

c - 段错误(核心转储)神经网络