混合使用硬件浮点ABI与不需要VFP/NEON的代码

3

场景

我的目标平台是启用了VFP/neon的ARM cortex-A7。在目标平台上运行的系统软件不总是打开VFP/neon,而是仅在需要时(通过调用某些系统API)打开。

我的工具链是在pc-cygwin主机(arm-none-eabi)上进行裸金属GCC-4.7.4交叉编译。

我们有一个C源文件a.c,该代码可能在系统软件关闭VFP/neon时运行。这个a.c代码是long long(64位整数)操作密集的纯整数代码。如果使用GCC选项-mfloat-abi=hard-mfloat-abi=softfp编译a.c,将生成一些使用VFP/neon寄存器的指令(例如vldr d7,[..]vstr d7,[sp,..]等)。如果在关闭VFP/neon时运行此生成的代码,则目标平台上会发生未定义故障。如果使用GCC选项-mfloat-abi=soft编译a.c,则不会使用VFP/neon寄存器,可以解决未定义故障问题。

另一方面,还有另一个C源文件b.c,其中包含浮点数/向量(VFP/neon)操作,并且仅在系统软件打开VFP/neon时运行。出于性能原因,我想使用GCC选项-mfloat-abi=hard而不是-mfloat-abi=softfp编译b.c

如果b.c使用-mfloat-abi=hard选项进行编译,而a.c使用-mfloat-abi=soft选项进行编译,则它们无法链接在一起,链接器将报错:"...Uses VFP register arguments, XXX does not"。

问题

有没有任何方法(使用工具链GCC选项、安装配置或版本),可以使这个纯整数的a.c兼容硬浮点ABI(通过VFP/neon寄存器传递浮点参数),但又不生成任何VFP/neon指令或寄存器来进行纯整数操作?

注释

  • 作为一种解决方法,可以使用选项-mfloat-abi=soft编译a.c,使用选项-mfloat-abi=softfp编译b.c,但是这会降低性能。
  • GCC 4.9发布说明中提到:“默认情况下禁用了在64位标量计算中使用高级SIMD(Neon)指令集。这只在少数情况下生成更好的代码。可以通过-mneon-for-64bits选项重新启用它。”这似乎与我的问题有关,但我正在使用GCC 4.7.4。
1个回答

0

无论如何,您应该坚持使用 softfp 选项。

事实上,当没有传递 float 类型的参数时,hardsoftfp 没有任何区别。

即使是这种情况,softfp 也会在可能循环之外的开始引入很小的开销。(将 ARM 寄存器的内容移动到 VFP 寄存器,并且在有超过四个参数时最终从堆栈加载一些内容)

由于 vfp 不支持 int64,以 v 开头的指令必须是 NEON 指令。您可以尝试使用 -fno-tree-vectorize 禁用愚蠢的自动向量化,该选项会自动启用 -o3

附注:如果您非常关注性能,为什么不编写优化的 NEON 代码呢?正确编写的 NEON 代码产生了惊人的差异,而那些令人讨厌的自动向量化代码几乎没用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接