我刚开始尝试使用NEON优化一些Android代码。不过,我遇到了一些问题。主要问题是我真的无法解决如何快速进行16位浮点转换。
我看到可以使用vcvt.s32.f32将多个32位整数转换为1个SIMD指令中的浮点数。但是,如何将一组4个S16转换为4个S32?我认为它与VUZP指令有关,但我无法弄清楚如何......
同样地,我看到可以使用VCVT.s16.f32一次将1个16位转换为浮点数,但是这很有用,但是不能使用SIMD这样做是非常浪费的。
多年来我在许多不同的平台上编写了汇编程序,但我发现ARM文档由于某种原因完全不可思议。
因此,任何帮助都会非常感激。
还有什么方法可以获得NEON设备的吞吐量和延迟数据吗?
提前致谢!
答案 0 :(得分:4)
如果不进行其他计算以及从16位整数到32位整数的转换,您可以选择 uint32x4_t = vmovl_u16(uint16x4_t)
如果在转换之前执行任何简单的加法或乘法等,您可以将它们组合在一个指令中,如 int32x4_t = vmull_u16(int16x4_t,int16x4_t)或 int32x4_t = vaddl_u16(int16x4_t) ,int16x4_t)等,从而节省了一些周期。
答案 1 :(得分:2)
在我的注释中详细说明:你想在转换为4个32位浮点数之前将4个16位寄存器“加宽”为4个32位整数。看看指令集,我认为没有更快的转换路径,但我很容易出错。
直接方法是将vaddl.s16
与第四个零的操作数一起使用,但除非您只进行转换,否则通常可以将转换与之前的操作结合使用。例如。如果你将两个int16x4寄存器相乘,你可以使用vmull.s16
直接获得32位输出,而不是先用乘法和加宽(假设你不依赖于任何截断行为)。
答案 2 :(得分:1)
为什么使用vaddl浪费周期用0?
初始化有价值的寄存器vmovl.s16 q0,d1
然后转换q0
将会这样做。
我的问题是: