ARM CPU的 intrinsics指令集 - svlsr_u32_z

在 ARM SVE(Scalable Vector Extension) intrinsics 指令集中,svlsr_u32_z 是带掩码的向量逻辑右移指令,用于对无符号 32 位整数(uint32_t)向量执行逻辑右移操作,并通过掩码(predicate)控制有效元素的运算,掩码无效位置的结果会被清零。其名称中 “lsr” 表示 “Logical Shift Right”(逻辑右移),“z” 表示 “zeroing”(清零模式)。

基本语法

 
svuint32_t svlsr_u32_z(
    svbool_t pg,               // 掩码:控制哪些元素参与运算并保留结果
    svuint32_t op,             // 待移位的无符号32位整数向量
    uint32_t shift             // 移位量:每个元素右移的位数(0 ≤ shift < 32)
);

参数说明

  1. pg(predicate mask)
    类型为 svbool_t 的掩码向量,决定运算的有效范围:
    • 掩码位为1的位置:对 op 向量中对应元素执行逻辑右移(op[i] >> shift),结果保留;
    • 掩码位为0的位置:结果直接清零(0),不参与移位运算。
  2. op
    类型为 svuint32_t 的向量,存储待执行逻辑右移的无符号 32 位整数元素。
  3. shift
    32 位无符号整数,表示每个元素的右移位数(统一的移位量,适用于向量中所有有效元素)。移位量必须在 [0, 31] 范围内(超出范围会导致未定义行为)。

核心功能

svlsr_u32_z 的核心是对向量中掩码有效的元素执行逻辑右移,高位补0,无效元素直接清零。逻辑右移的特点是:移位后高位用0填充,与算术右移(高位补符号位)不同,适用于无符号整数。

 

  • 示例:
    若 op = [0x80000000, 0x0000000F, 0xABCD1234, 0x12345678]
    shift = 4(右移 4 位),
    掩码 pg = [1, 1, 0, 1](仅第 0、1、3 位有效),
    则运算结果为:
    • 第 0 位:0x80000000 >> 4 = 0x08000000(高位补 0),
    • 第 1 位:0x0000000F >> 4 = 0x00000000
    • 第 2 位:掩码无效,结果为0
    • 第 3 位:0x12345678 >> 4 = 0x01234567
      最终结果向量为 [0x08000000, 0x00000000, 0x00000000, 0x01234567]

使用场景与示例

逻辑右移常用于提取低位数据、缩放无符号整数、位域解析等场景。例如,从 32 位无符号整数中提取高 16 位(通过右移 16 位实现):
#include <arm_sve.h>
#include <stdint.h>

// 从无符号32位整数数组中提取每个元素的高16位(右移16位)
void extract_high16(uint32_t* dst, const uint32_t* src, size_t len) {
    size_t i = 0;
    svcount_t vl = svcntw(); // 获取32位元素的向量长度(如8,对应256位SVE向量)
    svbool_t pg = svwhilelt_b32(i, len); // 生成初始掩码(标记有效元素)
    
    while (svptest_any(svptrue_b32(), pg)) {
        // 加载源数据向量(32位整数)
        svuint32_t src_vec = svld1_u32(pg, src + i);
        
        // 逻辑右移16位,提取高16位,掩码外元素清零
        svuint32_t dst_vec = svlsr_u32_z(pg, src_vec, 16);
        
        // 存储结果到目标数组
        svst1_u32(pg, dst + i, dst_vec);
        
        // 更新循环变量和掩码
        i += vl;
        pg = svwhilelt_b32(i, len);
    }
}

// 调用示例:
// uint32_t src[] = {0x12345678, 0xABCDABCD, 0x0000FFFF, 0xFFFF0000};
// uint32_t dst[4];
// extract_high16(dst, src, 4); 
// 结果:[0x00001234, 0x0000ABCD, 0x00000000, 0x0000FFFF]

关键注意事项

  1. 清零模式(z的含义)
    指令名称中的 “z” 表示掩码无效(0)的位置结果会被强制清零,这与不带 “z” 的指令(如svlsr_u32)不同:后者在掩码无效时会保留原始输入值,而svlsr_u32_z 直接输出0
  2. 统一移位量
    shift 是一个标量值(而非向量),表示对所有有效元素执行相同的移位位数。若需对不同元素使用不同移位量,需使用 svlsrv_u32_z(“v” 表示向量移位量)。
  3. 向量长度适配
    SVE 向量长度由硬件决定(如 256 位、512 位等),svlsr_u32_z 会自动适配当前长度,并行处理所有有效元素,无需手动适配不同硬件。
  4. 与算术右移的区别
    逻辑右移(lsr)高位补0,适用于无符号整数;算术右移(asr)高位补符号位,适用于有符号整数。使用时需根据数据类型选择正确的移位指令。

总结

svlsr_u32_z 是 SVE 中用于带掩码的无符号 32 位向量逻辑右移的指令,通过掩码控制有效元素的移位操作,无效元素清零。它在提取高位数据、缩放无符号整数等场景中应用广泛,利用 SVE 的向量并行性可大幅提升批量数据的移位效率。
posted @ 2025-08-13 14:56  lvmxh  阅读(11)  评论(0)    收藏  举报