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

使用SSE 4.2内建函数清零SSE寄存器首个零字节后剩余字节

使用SSE 4.2实现寄存器内首个零相关区域清零

针对你提出的需求——在SSE寄存器内找到首个零相关区域后清零后续内容,以下是基于SSE4.2内置函数的实现方案,全程在寄存器内完成操作,无需回写内存:

核心思路

利用SSE4.2的字符串比较指令快速定位目标位置,生成对应掩码后通过按位与操作完成清零,避免内存交互开销。

场景1:首个全0字节(0x00)后清零

如果需求是找到第一个全0字节,并将该字节之后的所有字节清零(保留该全0字节及之前的内容),可以用以下代码:

#include <smmintrin.h>

__m128i clear_after_first_full_zero_byte(__m128i input) {
    // 生成全0的模板寄存器
    const __m128i zero_template = _mm_setzero_si128();
    // 生成匹配全0字节的掩码:匹配位置为1,其余为0
    __m128i match_mask = _mm_cmpistrm(zero_template, input, 
                                      _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | 
                                      _SIDD_BIT_MASK | _SIDD_UNIT_BYTE);
    
    // 构造前缀保留掩码:从第一个全0字节开始,之后的位全为0
    __m128i prefix_mask = _mm_or_si128(match_mask, _mm_andnot_si128(_mm_slli_si128(match_mask, 1), _mm_set1_epi8(0xFF)));
    
    // 应用掩码清零后续字节
    return _mm_and_si128(input, prefix_mask);
}

场景2:首个含0位的字节后清零(匹配你的示例)

从你的示例来看,实际需求更可能是找到第一个包含0比特位的字节,将该字节内0位之后的所有位清零,同时清零后续所有字节。这种情况可以结合位查找指令实现:

#include <smmintrin.h>
#include <immintrin.h>

__m128i clear_after_first_zero_bit(__m128i input) {
    // 生成全1字节模板,用于查找非全1的字节(即含0位的字节)
    const __m128i all_one_template = _mm_set1_epi8(0xFF);
    // 找到第一个非全1的字节索引
    int byte_idx = _mm_cmpistri(all_one_template, input, 
                               _SIDD_CMP_NOT_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | 
                               _SIDD_BIT_MASK | _SIDD_UNIT_BYTE);
    
    // 所有字节都是全1,直接返回原数据
    if (byte_idx == 16) return input;
    
    // 提取目标字节并找到第一个0位的位置
    uint8_t target_byte = _mm_extract_epi8(input, byte_idx);
    int bit_pos = _lzcnt_u32(target_byte) - 24; // 计算高位开始的第一个0位位置
    
    // 生成目标字节的掩码:保留第一个0位之前的位
    uint8_t byte_mask = (0xFF << (8 - bit_pos)) & 0xFF;
    // 构造完整128位掩码:目标字节之后的所有字节清零
    __m128i mask = _mm_set1_epi8(0xFF);
    mask = _mm_srli_si128(mask, 16 - byte_idx);
    mask = _mm_slli_si128(mask, 16 - byte_idx);
    // 替换目标字节的掩码
    mask = _mm_insert_epi8(mask, byte_mask, byte_idx);
    
    // 应用掩码完成清零
    return _mm_and_si128(input, mask);
}

关键指令说明

  • _mm_cmpistri:SSE4.2字符串比较指令,快速在128位寄存器中查找符合条件的字节,返回匹配位置的索引。
  • _mm_cmpistrm:同系列指令,直接生成匹配位置的掩码,避免单独处理索引的开销。
  • _lzcnt_u32:计算无符号整数的前导1数量,用于定位字节内的第一个0位(需CPU支持BMI1指令集,通常与SSE4.2共存)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:26:18