支持 Android 的硬浮点数的 OpenCV

OpenCV with hard-float support for Android

我想在我的 Android 应用程序中使用硬件浮点支持,该应用程序大量使用 OpenCV 库。但是,当我为 hard-float 设置 gcc 标志时(如 here and here 所述),我收到链接器错误消息: XXX.o uses VFP register arguments, output does not。然后我添加链接器标志 -Xlinker --no-warn-mismatch 使这些错误消失但应用程序立即崩溃似乎是与 OpenCV 库的第一次交互。

到底是怎么回事?我是否正在编译代码的硬浮点版本并将其与软浮点 OpenCV 链接?

是否有一个版本的 OpenCV4Android 带有使用 hard-float 架构的预构建二进制文件?如果没有,是否可以编译这样的版本?一个人会怎么做?在使用 OpenCV 时是否有更聪明的方法来利用硬件浮点支持?

您无需在硬浮点模式下构建即可使用硬件浮点单元。只要您为 armeabi-v7a ABI 构建,它就会使用硬件浮点单元 (VFPv3)。

澄清一下,hard-float 选项(通过向编译器添加 -mhard-float 参数,或为 armeabi-v7a-hard ABI 构建)仅更改将参数传递给函数的方式。在内部,Android 在整数寄存器中传递所有 float/double 函数参数。这确保了为 armeabi 构建的代码(ARMv5 不保证浮点单元,需要以这种方式传递这些参数)在 FPU 上的现代设备上 运行 时仍然有效。即,函数获取整数寄存器中的所有浮点参数并将它们移至 FPU 寄存器以在函数内进行所有计算。

使用 hard-float 选项构建时,此类参数直接在 FPU 寄存器中传递,但正如您的第二个 link 指出的那样,这要求您调用的所有代码都使用相同的选项构建,并且 JNI 函数入口点需要用 JNICALL.

正确标记

因此,您从 hardfloat 中获得的实际好处只是您在每次函数调用中节省了一些指令(正如第一个 link 中的答案所指出的,这些非常便宜)。根据库的功能结构,这可能是一个完全无关紧要的更改,也可能很明显。不幸的是,我不太了解 OpenCV 的内部结构,无法猜测有多大的潜在加速(如果有的话)。

所以回顾一下,是的,你是对的,你只是在构建你的代码的硬浮点版本,但 link将它转换为 OpenCV 的软浮点 ABI 版本。为了使事情正常进行,您还可以在对 OpenCV 的所有函数调用上添加 __attribute__((pcs("aapcs"))) 标记,但这几乎会抛弃所有潜在的优势,因为所有繁重的工作(很可能)是在库中完成的,而不是在您的调用代码中。

因此,为了获得硬浮动 ABI 的潜在好处,您需要使用 -mhard-float 参数重建所有 OpenCV(具体如何操作,虽然我帮不了您).但只要它是针对 armeabi-v7a(使用 -march=armv7-a -mfpu=vfpv3 参数)构建的,它就应该已经在使用硬件 FPU,它只是使用向后兼容的 ABI。 softfp ABI 的开销比完整的 softfloat 版本(不是用 -mfpu=vfpv3 构建)的开销小几个数量级。