You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取SSE XMM寄存器中各16位数值的低8位并写入内存?

使用VS C++内部函数实现16位整数批量比较并生成uchar结果数组

针对你提出的批量处理需求,我们可以利用VS C++提供的SSE2内部函数完成128位向量运算,高效实现8个16位整数的范围比较,并将结果转换为uchar数组输出。以下是具体实现方案:

核心实现代码

#include <emmintrin.h>  // 引入SSE2内部函数头文件

// 批量处理8个16位整数,生成对应的uchar结果
void process_8_shorts(const short* wfin, unsigned char* predout, short tlower, short tupper) {
    // 加载8个16位整数到128位向量变量
    __m128i vec_v = _mm_loadu_si128((const __m128i*)wfin);

    // 将上下限标量广播到128位向量的所有16位元素
    __m128i vec_tlower = _mm_set1_epi16(tlower);
    __m128i vec_tupper = _mm_set1_epi16(tupper);

    // 执行范围比较,得到掩码(满足条件的元素为0xFFFF,否则为0x0000)
    __m128i mask_gt = _mm_cmpgt_epi16(vec_v, vec_tlower);  // v > tlower
    __m128i mask_lt = _mm_cmplt_epi16(vec_v, vec_tupper);  // v < tupper
    __m128i mask_both = _mm_and_si128(mask_gt, mask_lt);   // 同时满足两个条件的掩码

    // 将0xFFFF转换为0x0001,0x0000保持不变,对应标量代码的1/0
    __m128i vec_result = _mm_and_si128(mask_both, _mm_set1_epi16(1));

    // 将16位的1/0打包为8位的1/0,低8字节即为目标结果
    __m128i packed_result = _mm_packus_epi16(vec_result, vec_result);

    // 将低8字节写入predout数组(非对齐存储)
    _mm_storel_epi64((__m128i*)predout, packed_result);
}

// 处理任意数量的16位整数,自动分块批量处理
void process_all(const short* wfin, unsigned char* predout, size_t count, short tlower, short tupper) {
    size_t i = 0;
    // 批量处理8个元素的块
    for (; i + 7 < count; i += 8) {
        process_8_shorts(&wfin[i], &predout[i], tlower, tupper);
    }
    // 处理剩余不足8个的元素(使用标量代码兼容)
    for (; i < count; ++i) {
        short v = wfin[i];
        predout[i] = (v < tupper && v > tlower) ? 1 : 0;
    }
}

关键步骤说明

  • 向量加载与广播:_mm_loadu_si128从非对齐内存加载8个short到128位向量;_mm_set1_epi16将标量上下限广播到向量的所有16位元素,实现批量比较的基础。
  • 向量比较:_mm_cmpgt_epi16和_mm_cmplt_epi16是SSE2的有符号16位整数比较指令,满足条件的元素会被设置为0xFFFF,否则为0x0000。
  • 掩码合并与转换:通过_mm_and_si128合并两个比较掩码,得到同时满足范围条件的结果;再通过与0x0001按位与,将0xFFFF转换为0x0001,匹配标量代码的1/0输出。
  • 结果打包与存储:_mm_packus_epi16将16位的结果打包为8位,_mm_storel_epi64将低8字节写入uchar数组,完成最终输出。

注意事项

  • 指令集支持:需要在VS C项目属性中开启SSE2支持(路径:C/C -> 代码生成 -> 启用增强指令集,选择Streaming SIMD Extensions 2 (/arch:SSE2))。
  • 内存对齐优化:如果输入数组wfin和输出数组predout是16字节对齐的,可将_mm_loadu_si128替换为_mm_load_si128,_mm_storel_epi64替换为_mm_store_si128,进一步提升性能。

内容的提问来源于stack exchange,提问作者user2607207

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:28:13