【问题标题】:OpenCV with hard-float support for AndroidOpenCV 具有对 Android 的硬浮点支持
【发布时间】:2015-02-08 07:35:52
【问题描述】:
我想在我的 Android 应用程序中使用硬件浮点支持,它大量使用了 OpenCV 库。但是,当我为硬浮点设置 gcc 标志时(如 here 和 here 所述),我收到链接器错误消息:
XXX.o uses VFP register arguments, output does not。然后我添加链接器标志-Xlinker --no-warn-mismatch,这会使这些错误消失,但应用程序在似乎是与 OpenCV 库的第一次交互时立即崩溃。
到底发生了什么?我是否正在编译我的代码的硬浮点版本并将其与软浮点 OpenCV 链接?
是否存在具有使用硬浮点架构的预构建二进制文件的 OpenCV4Android 版本?如果没有,是否可以编译这样的版本?如何做到这一点?在使用 OpenCV 时,是否有更智能的方式来利用硬件浮点支持?
【问题讨论】:
标签:
android
c++
opencv
android-ndk
computer-vision
【解决方案1】:
您无需构建硬浮点模式即可使用硬件浮点单元。只要您为armeabi-v7a ABI 构建,它将使用硬件浮点单元(VFPv3)。
为了澄清,硬浮点选项(通过将-mhard-float 参数添加到编译器,或为armeabi-v7a-hard ABI 构建)只会改变参数传递给函数的方式。在内部,Android 在整数寄存器中传递所有浮点/双精度函数参数。这确保了为 armeabi(ARMv5 不保证浮点单元,需要以这种方式传递这些参数)构建的代码在 FPU 上的现代设备上运行时仍然有效。即,函数获取整数寄存器中的所有浮点参数,并将它们移至 FPU 寄存器以执行函数内的所有计算。
使用硬浮点选项构建时,此类参数直接在 FPU 寄存器中传递,但正如您的第二个链接指出的那样,这要求您调用的所有代码都使用相同的选项构建,并且 JNI 函数入口点需要用JNICALL正确标记。
因此,您从 hardfloat 获得的实际好处只是您在每次函数调用时节省了一些指令(正如第一个链接中的答案所指出的那样,这些指令非常便宜)。根据库的功能结构,这可能相当于一个完全微不足道的变化,或者可能是显而易见的。不幸的是,我对 OpenCV 内部的了解不够深入,无法猜测可能会有多大的潜在加速(如果有的话)。
所以回顾一下,是的,您是对的,您只是在构建代码的硬浮动版本,但将其链接到 OpenCV 的软浮动 ABI 版本。为了使事情顺利进行,您还可以在 OpenCV 中的所有函数调用上添加 __attribute__((pcs("aapcs"))) 标记,但这几乎会抛弃所有潜在的优势,因为所有繁重的工作(很可能)都是在库中完成的,而不是在您的调用代码。
因此,要获得硬浮动 ABI 的潜在好处,您需要使用 -mhard-float 参数重建所有 OpenCV(具体如何操作,但我无法帮助您)。但只要它是针对armeabi-v7a(带有-march=armv7-a -mfpu=vfpv3 参数)构建的,它就应该已经在使用硬件FPU,它只是使用向后兼容的ABI。 softfp ABI 的开销比完整的 softfloat 版本(不是用 -mfpu=vfpv3 构建的)的开销小几个数量级。