2

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

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

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

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

因此,我们将不胜感激任何帮助。

还有什么方法可以获取 NEON 单元的吞吐量和延迟数据?

提前致谢!

4

3 回答 3

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)等,从而节省一些周期。

于 2011-10-18T12:45:59.777 回答
2

详细说明我的评论:您想在转换为 4 个 32 位浮点数之前将 4 个 16 位寄存器“扩展”为 4 个 32 位整数。查看指令集,我认为没有更快的转换路径,但我很容易出错。

直接方法是使用vaddl.s16四个零的第二个操作数,但除非您只进行转换,否则您通常可以将转换与先前的操作结合起来。例如,如果您将两个 int16x4 寄存器相乘,您可以使用它vmull.s16来直接获得 32 位输出,而不是先相乘再扩大(前提是您不依赖于任何截断行为)。

于 2011-10-18T05:51:44.117 回答
1

为什么要使用 vaddl 浪费循环初始化一个有价值的寄存器为 0?

vmovl.s16 q0, d1

然后转换 q0

那会的。

我的问题是:

  • 是否绝对有必要将它们转换为浮动?NEON 进行整数运算比浮点运算快得多。(执行和流水线)因此,由于强大的长、宽、窄模型结合算术指令和自动舍入/饱和选项,定点操作在大多数情况下会更合适。

PS:奇怪,我认为 ARM 的 PDF 是最好的。

于 2011-11-01T06:59:16.807 回答