【发布时间】:2011-11-08 08:32:12
【问题描述】:
我正在尝试为 Cortex A9 ARM 处理器(更具体地说是 OMAP4)构建一个库,但对于在浮点上下文中何时使用 NEON 和 VFP 有点困惑操作和 SIMD。需要注意的是,我知道 2 个硬件协处理器单元之间的区别(也概述了 here on SO),我只是对它们的正确使用有一些误解。
与此相关,我正在使用以下编译标志:
GCC
-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
ARMCC
--cpu=Cortex-A9 --apcs=/softfp
--cpu=Cortex-A9 --fpu=VFPv3 --apcs=/softfp
我已经阅读了 ARM 文档、大量 wiki(like this one)、论坛和博客文章,似乎每个人都同意使用 NEON 比使用 VFP 更好 或者至少混合 NEON(例如,使用内部函数在 SIMD 中实现一些算法)和 VFP 并不是一个好主意;我还不能 100% 确定这是否适用于整个应用程序\库的上下文或仅适用于代码中的特定位置(函数)。
所以我使用霓虹灯作为我的应用程序的 FPU,因为我也想使用内在函数。结果我遇到了一些麻烦,我对如何在 Cortex A9 上最好地使用这些功能(NEON 与 VFP)的困惑只是进一步加深而不是理清。我有一些代码可以为我的应用程序进行基准测试并使用一些定制的计时器类 其中计算基于双精度浮点。使用 NEON 作为 FPU 会产生完全不合适的结果(尝试打印这些值会导致打印主要是 inf 和 NaN;相同的代码在为 x86 构建时可以顺利工作)。所以我改变了我的计算以使用单精度浮点,因为记录表明 NEON 不处理双精度浮点。我的基准测试仍然没有给出正确的结果(最糟糕的是,现在它在 x86 上不再工作了;我认为这是因为精度下降,但我不确定)。所以我几乎完全迷失了:一方面我想将 NEON 用于 SIMD 功能,并将其用作 FPU 并不能提供正确的结果,另一方面将它与 VFP 混合似乎不是一个好主意。 非常感谢这方面的任何建议!
我在上面提到的 wiki 的文章中找到了在 NEON 的上下文中应该为浮点优化做些什么的总结:
"
- 仅使用单精度浮点
- 当您发现瓶颈 FP 函数时,请使用 NEON 内部函数/ASM。你可以比编译器做得更好。
- 最小化条件分支
- 启用 RunFast 模式
对于softfp:
- 内联浮点代码(除非它非常大)
- 通过指针而不是通过值传递 FP 参数,并在函数调用之间执行整数运算。
"
我不能硬使用浮动 ABI,因为我无法链接到我可用的库。 大多数建议对我来说都是有意义的(除了“runfast 模式”,我不完全理解应该做什么以及此时我可以做得比编译器更好的事实)但我一直得到不一致的结果和我现在什么都不确定。
谁能阐明如何正确使用 Cortex A9/A8 的浮点和 NEON 以及我应该使用哪些编译标志?
【问题讨论】:
-
也试一试自动矢量化。如果使用 ARM RVCT 编译器,请将 --vectorize 添加到命令行(您可能需要专业的 RVCT 许可证才能尝试此操作,因此请记住这一点)
-
您的建议与 SIMD 有关。我的问题是关于正确使用 VFP 单元的任一 NEON 的浮点功能。
标签: c++ c floating-point arm neon