OpenCV,支持Android的硬浮动

Sta*_*tav 0 c++ android opencv computer-vision android-ndk

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

到底发生了什么?我是否正在编译我的代码的硬浮版本并将其与软浮动OpenCV相关联?

是否有一个OpenCV4Android版本的预构建二进制文件使用硬浮动架构?如果没有,是否可以编译这样的版本?如何做到这一点?在使用OpenCV时,是否有更智能的方法来利用硬件浮点支持?

mst*_*sjo 6

您不需要构建硬浮点模式以使用硬件浮点单元.只要你为armeabi-v7aABI 构建,它就会使用硬件浮点单元(VFPv3).

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

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

因此,从hardfloat获得的实际好处仅在于您为每个函数调用保存了一些指令(并且正如第一个链接中的答案指出的那样,这些非常便宜).根据库的功能结构,这可能相当于一个完全无关紧要的变化,或者可能是显而易见的.不幸的是,我不知道OpenCV的内部结构是否足以猜出有多大的潜在加速,如果有的话.

所以回顾一下,是的,你是对的,你只是构建一个硬浮版本的代码,但将它链接到一个软浮动ABI版本的OpenCV.为了使事情有效,你还可以__attribute__((pcs("aapcs")))在所有函数调用中添加标记到OpenCV中,但这几乎会抛弃所有潜在的优势,因为所有繁重的工作(最有可能)都是在库中完成的,而不是在你的调用代码中.

因此,要获得硬浮ABI的潜在好处,您需要使用-mhard-float参数重建所有OpenCV (具体如何做到这一点,但我无法帮助您).但只要它是针对armeabi-v7a(使用-march=armv7-a -mfpu=vfpv3参数)构建的,它应该已经使用硬件FPU,它只使用向后兼容的ABI.softfp ABI的开销比完整的softfloat版本(未内置-mfpu=vfpv3)的开销小几个数量级.