D.9.1 VLD1 && VLD1Q
平平无奇,也是最常用的读取内存操作,比如U8版本,一次性读入8个uint8_t
Q版本度的数量翻倍
D.9.2 VLD1_LANE && VLD1Q_LANE
用于从不连续的内存中读取数据
意思是把Scalar_t的数据存入Vector_t的第int range个位置,并将整个Vector_t存放到Result_t里,通常Vector_t跟Result_t是同一个
D.9.3 VLD1_DUP && VLD1Q_DUP
批量复制输入值进neon寄存器
比如u8版本,输入一个uint8_t a, 以uint8x8_t的形式输出8个一模一样的a
Q版本数量翻倍
D.9.4 VLD2 && VLD2Q
这张图非常形象地解释了vld2作用:交错地读一块内存,并分别将结果存入两块不同的NEON寄存器
拿u16版本举例:
(寄存器a,寄存器b)= vld2_u16(内存c),其中 内存c={1,2,3,4,5,6,7,8}
那么结果就是 寄存器a = {1,3,5,7};寄存器b = {2,4,6,8}
Q版本搬运数量翻倍
D9.5 VLD2_LANE
应该与VLD1_LANE类似,但有点抽象,等我用到了再补充
D9.6 VLD2_DUP
从Scalar_t连续读两个变量,分别批量复制到Result_t的两个NEON寄存器中
比如 (寄存器a,寄存器b)= vld2_dup_u16(内存c),其中 内存c = {1,2}
结果是 寄存器a = {1,1,1,1},寄存器b = {2,2,2,2}
这个算子没有Q版本
D.9.7~9.9 VLD3 && VLD3Q && VLD3_LANE && VLD3Q_LANE && VLD3_DUP
VLD3系列跟VLD2系列类似,就是再多读了一块内存,这里就跳过不讲了,麻烦读者重温上文的vld2系列算子
VLD3Q、 VLD3Q_LANE读的数量翻倍,VLD3_DUP没有Q版本
D.9.10~9.12 VLD4 && VLD4Q
vld4系列算子跟VLD2系列类似,就是再多读了两块内存,这里就跳过不讲了,麻烦读者重温上文的vld2系列算子
VLD4Q、 VLD4Q_LANE读的数量翻倍,VLD4_DUP没有Q版本
D.9.13 VST1 && VST1Q
最简单的写存算子,把NEON寄存器Vector_t中的数据存到通用内存Scalar_t中。
Q版本数量翻倍
D.9.15 VST2 && VST2Q
把连续两块向量寄存器中的数据存入一块通用内存
Q版本数量翻倍
D.9.14 VST1_LANE && VST1Q_LANE
把向量寄存器Vector_t的第range个位置中的数据存到通用内存Scalar_t
比如u16版本:vst1_lane_u16(内存a,向量b,2);其中b={5,6,7,8};
那么结果是a=7
Q版本数量翻倍
D.9.16 VST2_LANE && VST2Q_LANE
把两块向量寄存器Vector_t的第range个位置中的数据存到通用内存Scalar_t,参考VST1_LANE
D.9.17~9.20 VST3 && VST3Q && VST3_LANE && VST3Q_LANE && VST4 && VST4Q && VST4_LANE && VST4Q_LANE
参考D.9.10~9.16,这些功能重复的算子我真的写出ptsd了
D.9.21 VGET_LANE
D.9.22 VSET_LANE
D.11.2 VDUP_N && VDUPQ_N
那这个又是啥呢。。好像作用跟VLD1_DUP一样?