使用ARM neon将短数组转换为浮点数

时间:2011-10-17 20:49:24

标签: android c arm assembly neon

我刚开始尝试使用NEON优化一些Android代码。不过,我遇到了一些问题。主要问题是我真的无法解决如何快速进行16位浮点转换。

我看到可以使用vcvt.s32.f32将多个32位整数转换为1个SIMD指令中的浮点数。但是,如何将一组4个S16转换为4个S32?我认为它与VUZP指令有关,但我无法弄清楚如何......

同样地,我看到可以使用VCVT.s16.f32一次将1个16位转换为浮点数,但是这很有用,但是不能使用SIMD这样做是非常浪费的。

多年来我在许多不同的平台上编写了汇编程序,但我发现ARM文档由于某种原因完全不可思议。

因此,任何帮助都会非常感激。

还有什么方法可以获得NEON设备的吞吐量和延迟数据吗?

提前致谢!

3 个答案:

答案 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

将会这样做。

我的问题是:

  • 将它们转换为浮动是否绝对必要? NEON比float更快地进行整数运算。 (执行和流水线)因此,由于强大的长,宽,窄模型结合算术指令和自动圆/饱和选项,定点运算在大多数情况下更合适。
PS:奇怪,我认为ARM的PDF是最好的。