NDK编译——x86 支持

文章的内容是从Android开发者官网扒的,为了防止再登不上去,记录一下。官网网址:https://developer.android.com/ndk/guides/x86.html


x86 支持

NDK 引入对 x86 ABI 的支持,其允许原生代码在 CPU 可支持 IA-32 指令集的 Android 设备上运行。

概览


如需生成 x86 机器代码,请将 x86 添加到 Application.mk 文件中的 APP_ABI 定义。 例如:

APP_ABI := armeabi armeabi-v7a x86
如需了解有关定义  APP_ABI 变量的详细信息,请参阅  Application.mk

构建系统将生成的库放入 $PROJECT/libs/x86/(其中 $PROJECT 表示您的项目的根目录)并其嵌入 /lib/mips/ 下的 APK 中。

在兼容的基于 x86 的设备上安装 APK 时,Android 软件包提取这些库,将它们置于应用的私有数据目录下。

在 Google Play 商店中,服务器过滤应用,以便消费者只能看到可在其设备所配备的 CPU 上运行的原生库。

x86 对 ARM NEON 内联函数的支持


通过与标准 ARM NEON 内联函数标头 arm_neon.h 具有相同名称的 C/C++ 语言标头为 ARM NEON 内联函数提供支持。 这些标头适用于所有 NDK x86 工具链。 它们将 NEON 内联函数转换为原生 x86 SSE 内联函数。

此解决方案的特性包括下列各项:

  • 默认使用 SSE 到 SSSE3 指令集将 ARM NEON 移植到 Intel SSE,涵盖所有 NEON 函数的 93% 左右(1869 个(总数为 2009 个))。
  • 将 ARM NEON 128 位矢量重新定义为均等的 x86 SIMD 数据。
  • 如果存在 1:1 对应关系,则将来自 ARM NEON 的一些函数重新定义为 Intel SSE。
  • 使用 Intel SIMD(如果它将生成一个性能结果)实现某些 ARM NEON 函数。
  • 使用序列化解决方案实现部分剩余的 NEON 函数,并发送相应的“低性能”编译器警告。

性能

大多数情况下,您应该能够取得类似于从 ARM NEON 代码获取的性能。 实现最佳结果的建议包括:

  • 使用 16 位数据对齐以实现更快地加载和存储速度。
  • 避免将 NEON 函数与常量一起使用。使用常量会导致因必须加载常量而造成的性能损失。 如果您必须使用常量,则尝试在热点环路之外初始化它们。 如果可以,将它们替换为逻辑运算和比较运算。
  • 尽量避免使用标记为“依次实现”的函数,因为它们需要将来自寄存器的数据存储到内存。 替代的做法是依次处理它们并重新加载。您可以更改用于矢量化整个端口的数据类型或算法,而不是进行序列化。

如需了解有关此主题的详细信息,请参阅从 ARM NEON 到 Intel SSE – 自动移植解决方案提示与技巧

与 ARM 版本的已知差异

大多数情况下,对于 NEON,x86 实现生成与 ARM 实现相同的结果。x86 实现几乎始终传递 NEON 测试。 但在几个极端情况下,x86 实现生成不同于其 ARM 实现的结果。 已知的不兼容性如下:

  • VRECPS/VRECPSQ
    如果一个操作数为 +/- 无限值,则第二个操作数为 +/- 0.0:
  • VRSQRTS/VRSQRTSQ
    如果一个操作数为 +/- 无限值,则第二个操作数为 +/- 0.0:
  • VMAX/VMAXQ
    如果一个操作数为 NaN,或两个操作数均为 +/- 0.0:
    • 在 ARM CPU 上,浮点最大值工作原理如下:
      • max(+0.0, -0.0) = +0.0。
      • 如果任意输入为 NaN,则对应的结果元素为默认 NaN。
      如需有关此条件和结果的详细信息,请参阅 ARM 编译器工具链汇编程序参考,忽略“被取代”水印。
    • 在 x86 CPU 上,浮点最大值工作原理如下:
      • 如果其中一个源操作数为 NaN,则返回第二个源操作数。
      • 如果两个源操作数均等于 0,则返回第二个源操作数。
      如需了解有关这些条件和结果的详细信息,请参阅 Intel® 64 和 IA-32 架构软件开发者手册的第 1 册附录 E 部分 E.4.2.3 和第 2 册第 3-488 页。
  • VMIN/VMINQ
    如果一个操作数为 NaN,或两个操作数均为 +/- 0.0:
    • 在 ARM CPU 上,浮点最小值工作原理如下:
      • min(+0.0, -0.0) = -0.0。
      • 如果任意输入为 NaN,则对应的结果元素为默认 NaN。
      如需有关此条件和结果的详细信息,请参阅 ARM 编译器工具链汇编程序参考,忽略“被取代”水印。
    • 在 x86 CPU 上,浮点最小值工作原理如下:
      • 如果其中一个源操作数为 NaN,则返回第二个源操作数。
      • 如果两个源操作数均等于 0,则返回第二个源操作数。
      如需了解有关这些条件和结果的详细信息,请参阅 Intel® 64 和 IA-32 架构软件开发者手册的第 1 册附录 E 部分 E.4.2.3 和第 2 册第 3-497 页。
  • VRECPE/VRECPEQ
    这些指令在 ARM 和 x86 CPU 上提供不同程度的准确性。如需了解有关这些差异的详细信息,请参阅 ARM 网站上的如何使用 VRECPE/VRECPEQ 进行反向预估?以及 Intel® 64 和 IA-32 架构软件开发者手册第 2 册第 4-281 页。
  • VRSQRTE/VRSQRTEQ

示例代码

如果您的项目确保添加 arm_neon.h 标头,则在您的 APP_ABI 的定义中定义 include x86。 然后,构建系统将您的代码移植到 x86。

有关将 ARM NEON 移植到 x86 SSE 的原理的示例,请参阅 hello-neon 示例。

独立工具链


您可以将 x86 ABI 纳入您自己的工具链中。如需了解详细信息,请参阅独立工具链

兼容性


x86 支持至少需要 Android 2.3 版本(Android API 级别 9)。如果您的项目文件面向较早的 API 级别,但添加 x86 作为目标平台,则 NDK 构建脚本自动为您选择正确的原生平台标头/库的集合。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值