__riscv_vlse32_v_f32m4 是 RISC-V 向量扩展(RVV)Intrinsics 里用于 跨步(strided)加载 32-bit 浮点数据 到向量寄存器的函数,其原型与要点如下:
1. 原型(GCC/Clang 内置)
1 2 3 4 5 6
| #include <riscv_vector.h>
vfloat32m4_t __riscv_vlse32_v_f32m4( const float *base, ptrdiff_t stride, size_t vl);
|
- 返回:
vfloat32m4_t 类型的向量寄存器组,最多可持有 vl 个 float 元素。
- 寻址方式:第 i 个元素地址 =
base + i * stride(字节)。
- stride 可为负,因此既能正向也能反向跨步加载。
- vl 由
vsetvl_e32m4(n) 计算得到,表示“当前硬件一次能处理的元素数”。
2. 功能与场景
- 把 非连续(间隔)内存中的
float 加载到向量寄存器,用于后续向量计算。
- 典型场景:
– 二维/三维数组按行/列访问(列主序时列间隔 ≠ 1)
– 稀疏矩阵中固定步长的“切片”
– 信号处理中的降采样(stride = 采样间隔)
3. 最小示例
1 2 3 4 5 6 7 8 9 10
| float a[100] = {...}; size_t n = 20; ptrdiff_t col_stride = sizeof(float) * 5;
size_t vl; for (size_t i = 0; i < n; i += vl) { vl = vsetvl_e32m4(n - i); vfloat32m4_t vec = __riscv_vlse32_v_f32m4(&a[i], col_stride, vl); }
|
4. 与连续加载对比
| 连续加载 |
跨步加载 |
vle32_v_f32m4(ptr, vl) |
vlse32_v_f32m4(ptr, stride, vl) |
地址 = ptr + i |
地址 = ptr + i * stride |
| 带宽最高 |
带宽降低,但支持非连续布局 |
5. 注意事项
- stride 以字节为单位,不是元素个数。
- 若 stride = 0,则退化成“广播”同一地址的值(可用于填充向量)。
- 当 stride < 0 时,base 应指向 末元素,实现反向加载。
- 对齐:RVV 不对跨步加载做地址对齐要求,但 对齐到元素大小 可提升性能。
一句话总结
__riscv_vlse32_v_f32m4 就是 RVV 的 向量跨步加载 指令 vlse32.v 的 C 语言 Intrinsic 封装,用来把 间隔排布 的 32-bit 浮点数据一次性搬进向量寄存器,是稀疏/二维数据向量化的关键入口。