12

Xamarin 文档对此有点不清楚。如果我在构建首选项中仅勾选 armeabi 来构建我的应用程序,我的应用程序是否会:

  1. 在 Play 商店中可用于 v7a 设备吗?
  2. 在 v7a 设备上运行?

如果它确实运行,是否有任何功能,如使用线程会导致意外行为或崩溃?

我有一个简单的应用程序,并试图保持它的小。另外,我没有 v7a 设备来进行快速实验。

澄清:

虽然似乎已明确接受仅使用 amreabi 库编译 Android 应用程序是“安全的,但性能不高”(请参阅​​这篇出色的帖子:Why use armeabi-v7a code over armeabi code?),Xamarin 文档我假设适用于他们编译的 .so 库的CPU 架构说:

请务必记住,Xamarin.Android 使用的 armeabi 运行时是线程安全的。如果将支持 armeabi 的应用程序部署到 armeabi-v7a 设备上,将会出现许多奇怪且无法解释的异常。

从那以后,我已经能够测试我刚刚在 v7a 设备上使用 armeabi 编译的应用程序,并且还没有遇到任何“奇怪且无法解释的异常”。

更新:

看起来 Xamarin 文档已经更新,现在(2014-07-14)读取:

请务必记住,Xamarin.Android 使用的 armeabi 运行时不是线程安全的。如果将支持 armeabi 的应用程序部署到 armeabi-v7a 设备上,将会出现许多奇怪且无法解释的异常。

4

4 回答 4

8

根据 Xamarin Android 文档,armeabi 代码将在多核 armeavi-v7 设备上以意想不到的方式崩溃。

http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture

第 1.1 节

注意:Xamarin.Android 的 armeabi 代码不是线程安全的,不应在多 CPU armeabi-v7a 设备上使用(如下所述)。在单核 armeabi-v7a 设备上使用 aremabi 代码是安全的。

Xamarin Android 要求包含 armeabi-v7a 的原因与线程安全内存访问有关。简而言之,armeabi 指令集缺少安全锁定 SMP 设备上的内存所需的指令。

可以在此错误报告中找到对该问题最彻底的讨论:https ://bugzilla.xamarin.com/show_bug.cgi?id=7013

乔纳森·普赖尔 2012-09-20 11:41:45 EDT

据我所知,在 SMP armeabi-v7a 设备上安全使用 armeabi 库是(几乎)不可能的。这是因为 armeabi 缺少在 SMP 设备上安全锁定数据所需的 CPU 指令,因此如果 armeabi 库包含必须防止多线程访问的数据,它就会被破坏,而 libmonodroid.so 就是这样一个库。这可以通过创建一个动态确定运行时 CPU 的 libmonodroid.so 来解决,允许它相应地使用 armeabi 或 armeabi-v7a 锁定指令,但这还没有完成,实现时间框架未知。

因此,如果您的应用程序将在 SMP 硬件上运行,您应该在您的应用程序中包含 armeabi-v7a 运行时。这可以在“项目选项”对话框中完成。

当您遇到随机内存损坏和分段错误时,这些崩溃很少见,但却是灾难性的并且很难调试。

我能够在 Galaxy S3 上可靠地重现该问题。此错误报告中有一些演示崩溃的示例代码:https ://bugzilla.xamarin.com/show_bug.cgi?id=7167


未知此错误是否会影响 Android 上的其他 NDK 应用程序。但它肯定会影响 Xamarin Android。

于 2013-10-01T06:27:36.280 回答
7

我点击并阅读了 Xamarin 评论。根据阅读它们,我认为您问错了问题。您提出的问题的答案是(正如 CommonsWare 在他的评论中所说),“是的,除非 Xamarin 搞砸了”。不幸的是,他们的文档表明他们认为他们确实搞砸了。他们的文档中有一些拼写错误使事情有些混乱,特别是在一个地方(第 1.1 节),当他们明确表示“不是线程安全的”时,他们说“是线程安全的”。他们在第 1.2 节中正确地重申了这一点:

注意:Xamarin.Android 的 armeabi 代码不是线程安全的,不应在多 CPU armeabi-v7a 设备上使用(如下所述)。在单核 armeabi-v7a 设备上使用 aremabi 代码是安全的。

我认为,如果您结合第 1.2 节和第 1.1 节中的信息,Xamarin 告诉您的内容就很清楚了。需要明确的是,我只是重申他们的文档所说的内容,而不是对其文档的真实性做出任何断言。也就是说,如果 armeabi 库(不是线程安全的)被加载到多核或多处理器设备上,可能会发生不好的事情。这种情况可能是由于 ICS (4.0.0-4.0.3) 中的错误引起的。所以:

使用 Xamarin.Android 4.2 或更低版本构建的应用程序应明确指定 armeabi-v7a 作为唯一的基于 ARM 的 ABI

以下是他们文档中的实际信息(添加了格式),重新排列成可能有助于使其更清晰的顺序:

从第 1.2.1 节

注意:Xamarin.Android 的 armeabi 代码不是线程安全的,不应在多 CPU armeabi-v7a 设备上使用(如下所述)。在单核 armeabi-v7a 设备上使用 aremabi 代码是安全的。

从第 1.1 节

由于 Android 4.0.0、4.0.1、4.0.2 和 4.0.3 中的错误,即使存在 armeabi-v7a 目录并且设备是 armeabi,也会从 armeabi 目录中获取本机库-v7a 设备。

注意:由于这些原因,强烈建议使用 Xamarin.Android 4.2 或更低版本构建的应用程序应明确指定 armeabi-v7a 作为唯一基于 ARM 的 ABI。

我认为基于文档的其余部分,这就是第 1.1 节的第一段应该说的(粗体编辑是我的):

应用程序二进制接口将在下面详细讨论,但重要的是要记住 Xamarin.Android 使用的 armeabi 运行时不是线程安全的。如果将支持 armeabi 的应用程序部署到多 CPU armeabi-v7a 设备上,则会出现许多奇怪且无法解释的异常。

于 2013-07-11T15:41:51.533 回答
3

http://www.arm.com/products/processors/instruction-set-architectures/index.php

如果你看这张图,它解释了 ARM 处理器设计的精神。ARM 设计

新的迭代扩展了基本功能集,但不要更改它。NEON 和 SIMD 需要直接引用才能使用,因此不能从 ARMv5 二进制文件中引用。除非你的二进制文件很大(那是实际的可执行文件,而不是整个 APK),否则我会编译两者并获得两全其美的效果。有关详细信息,请参阅此问题

无论如何,我会联系 Xamarin 以澄清那个稍微加载的“无法解释的异常”声明。如果他们发现在多个处理器上运行的代码存在问题,那么无论内核数量如何,他们的代码本质上都不是线程安全的。

于 2013-07-11T13:35:05.630 回答
0

是的。

armeabi 是通用基础,armeabi-v7a 包含一些在 armeabi 指令集中没有的附加指令。v7a 支持硬件浮点运算,如果它正在执行任何浮点运算,它可以使您的代码更快。如果硬件支持,Android 将首先尝试加载 armeabi-v7a 库,但如果不支持,它将回退到 armeabi 版本。

于 2013-07-10T03:41:58.890 回答