本文将分享如何在androidx86_64中运行armv8a应用程序的详细内容,此外,我们还将为大家带来关于11是ISOc++下x86_64、arm或其他架构的有效输出吗?、Android关于arm6
本文将分享如何在 android x86_64 中运行 arm v8a 应用程序的详细内容,此外,我们还将为大家带来关于11 是 ISO c++ 下 x86_64、arm 或其他架构的有效输出吗?、Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题、Android 模拟器支持运行 ARM 应用,Android 11 系统映像可直接将 ARM 指令转换成 x86 指令、android手机适配硬件平台:armeabi,armeabi-v7a,arm64-v8a的相关知识,希望对你有所帮助。
本文目录一览:- 如何在 android x86_64 中运行 arm v8a 应用程序
- 11 是 ISO c++ 下 x86_64、arm 或其他架构的有效输出吗?
- Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题
- Android 模拟器支持运行 ARM 应用,Android 11 系统映像可直接将 ARM 指令转换成 x86 指令
- android手机适配硬件平台:armeabi,armeabi-v7a,arm64-v8a
如何在 android x86_64 中运行 arm v8a 应用程序
如何解决如何在 android x86_64 中运行 arm v8a 应用程序
我尝试安装 libhoudini,但仍然无法运行 ARM 应用程序,尤其是主要操作系统(0.4.5 最终版本)中的 ARM-v8a 应用程序。有没有其他办法解决
11 是 ISO c++ 下 x86_64、arm 或其他架构的有效输出吗?
如何解决11 是 ISO c++ 下 x86_64、arm 或其他架构的有效输出吗?
这个问题基于Can''t relaxed atomic fetch_add reorder with later loads on x86,like store can? 我同意给出的答案。 在 x86 上 00 永远不会发生,因为 a.fetch_add 有一个锁前缀/完整屏障,并且加载不能在 fetch_add 以上重新排序,但在其他架构上,例如 arm/mips,它可以打印 00 >.我有两个关于 x86 和 arm 上的存储缓冲区的后续问题。
我的电脑(核心 i3 x86_64)从来没有得到 11,即 11 是一个有效的输出 iso c++ 中的 x86 ,所以我遗漏了什么? @Daniel Langr 证明 11 是 x86 上的有效输出。
现在 x86_64 有一个优势 fetch_add 作为一个完整的屏障。
对于 arm64 ,由于 cpu 指令重新排序,有时输出可能为 00。
对于 arm64 或其他一些架构,如果不重新排序,输出可以是 00 吗?。我的问题 是基于此。函数 foo 的存储缓冲区值 a.fetch_add(1) 对 bar 的 a.load() 和 b.fetch_add(1) 不可见 > 是 对 foo 的 b.load() 不可见。因此,我们无需重新排序即可获得 00。这会在 ISO C++ 下在不同的架构上发生吗?
// g++ -O2 -pthread axbx.cpp ; while [ true ]; do ./a.out | grep "00" ; done
#include<cstdio>
#include<thread>
#include<atomic>
using namespace std;
atomic<int> a,b;
int reta,retb;
void foo(){
a.fetch_add(1,memory_order_relaxed); //add to a is stored in store buffer of cpu0
//a.store(1,memory_order_relaxed);
retb=b.load(memory_order_relaxed);
}
void bar(){
b.fetch_add(1,memory_order_relaxed); //add to b is stored in store buffer of cpu1
//b.store(1,memory_order_relaxed);
reta=a.load(memory_order_relaxed);
}
int main(){
thread t[2]{ thread(foo),thread(bar) };
t[0].join(); t[1].join();
printf("%d%d\\n",reta,retb);
return 0;
}
解决方法
是的,ISO C++ 允许这样做;正如丹尼尔指出的那样,一种简单的方法是在 RMW 之后,在加载之前放置一些缓慢的东西,这样在两个线程都有机会增加之前它们不会执行。这应该是显而易见的,因为它不需要任何运行时重新排序发生,只是程序顺序的简单交错。 (所以 ISO C++ 允许 11
即使使用 seq_cst。)也就是说,您可以通过单独单步执行每个线程来实现这一点。
您是否想知道如何在没有延迟循环的情况下在 x86 上创建实际演示?
尝试将原子变量放在不同的缓存行中,以便两个不同的内核可以并行写入它们。
alignas(64) std::atomic<int> a,b; // the alignas applies to each separately
将它们放在同一个缓存行中,就像默认情况下可能发生的那样,获得它们所在的缓存行所有权的核心将能够在完全加载后立即执行另一个 var 的加载-增量的屏障部分完成。完成 RMW 意味着该内核的 L1d 缓存中的缓存线已经很热。 (内核只能在通过 MESI 获得独占所有权后才能修改缓存行,这也将使其对读取有效。)
因此,一个线程的两个操作极有可能在另一个线程的任一操作之前发生。 (在 x86 asm 中,每个操作都具有与其 seq_cst 等价物相同的 asm,因此我们可以在不丢失任何内容的情况下讨论全局操作顺序。)
可能唯一能阻止这种情况发生的是在 RMW 和负载之间恰到好处的时间到达的中断。
您还提出了一个单独的问题:
如果不重新排序,输出可以是00吗?
显然没有。程序顺序的交错不能将两个加载放在任一增量之前,因此需要运行时或编译时重新排序才能创建 00
效果。
a.fetch_add(1,memory_order_relaxed); // foo1
retb=b.load(memory_order_relaxed); // foo2
b.fetch_add(1,memory_order_relaxed); // bar1
reta=a.load(memory_order_relaxed); // bar2
随意混合,不要将 foo2 放在 foo1 之前或 bar2 放在 bar1 之前。
即如果单独单步执行每个线程,则永远看不到 00
。 当然,mo_relaxed
的全部意义在于它可以重新排序。指定“无需重新排序”与“使用 seq_cst”相同。
存储缓冲区的效果是一种重新排序,specifically Store Load reordering。 mo_seq_cst
甚至可以阻止这种情况,这是 seq_cst 的一部分,也是它如此昂贵的原因,尤其是对于纯存储操作。
Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题
Android 设备的CPU类型(通常称为”ABIs”)
引用: https://blog.csdn.net/ouyang_peng/article/details/51168072
- armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它.
- arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。
- armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多。
- x86: 平板、模拟器用得比较多。
- x86_64: 64位的平板。
问题描述
今天测试人员测试集成版本时除了一个bug:关于华为 Mate 8手机Android 6.0系统运行刚刚提测的版本时,出现闪退的bug,而小米 4 手机Android 6.0系统却没有出现任何bug,运行良好。后来查看本人相关模块的代码,发现本人集成版本相关模块的代码和分支版本相关模块的代码是一模一样的,那就是说本人把分支代码合并到主干代码是没有问题的,所以去查看主干代码的问题。
经过一番查看提交日志,发现有位同事再我合并代码之前,提交了一个关于友盟推送的so文件的记录,原来他加入了一个arm64-v8a文件夹,里面有友盟推送的arm64-v8a的so库文件。而其他的so库文本却没有arm64-v8a对应的版本。
通过百度查到知乎有一段关于arm64-v8a的解释:
arm64-v8a是可以向下兼容的,但前提是你的项目里面没有arm64-v8a的文件夹,如果你有两个文件夹armeabi和arm64-v8a,两个文件夹,armeabi里面有a.so 和 b.so,arm64-v8a里面只有a.so,那么arm64-v8a的手机在用到b的时候发现有arm64-v8a的文件夹,发现里面没有b.so,就报错了,所以这个时候删掉arm64-v8a文件夹,这个时候手机发现没有适配arm64-v8a,就会直接去找armeabi的so库,所以要么你别加arm64-v8a,要么armeabi里面有的so库,arm64-v8a里面也必须有
发现原来华为 Mate 8手机是64位的操作系统,而小米 4 手机是32位的操作系统,所以小米 4 手机手机运行APP没bug,而华为 Mate 8手机运行APP出现闪退bug。
解决方法
1、解决之前的截图:
从截图可以看出来,第一个项目中有 arm64-v8a,而没有x86目录,第二个项目中没有arm64-v8a,而有x86目录。第一个项目是作为项目引用导入到第二个项目中的。
2、解决后的截图:
从截图可以看出来,第一个项目中和第二个项目中没有的libs目录下,都是armeabi-v7a、armeabi、x86三个目录,保持一致。第一个项目是作为项目引用导入到第二个项目中的。
3、解决方法:
解决方法是:从友盟官方中去下载x86的相关so文件,放在x86目录下,把arm64-v8a目录删除。将所有关于so文件的都要保持一致,即:如果你要添加一个armeabi-v8a目录,下面放第三方的armeabi-v8a相关的so文件,那么你其他的so文件都要有相应想armeabi-v8a版本,不然就会报错。
4、建议
来自于博客:《与 .so 有关的一个长年大坑 》给的建议是:
- 为了减小 apk 体积,只保留 armeabi 和 armeabi-v7a 两个文件夹,并保证这两个文件夹中 .so 数量一致
- 对只提供 armeabi 版本的第三方 .so,原样复制一份到 armeabi-v7a 文件夹
下面文章转载于asce1885(简书作者):关于Android的.so文件你所需要知道的
(原文链接:关于Android的.so文件你所需要知道的)
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种!
Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。
应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。
为什么你需要重点关注.so文件
如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文件了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经嵌入了.so文件,并依赖于不同的ABI。
例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable,SQLCipher等,你都已经在生成的APK文件中包含.so文件了,而你需要关注.so文件。
Android应用支持的ABI取决于APK中位于lib/ABI目录中的.so文件,其中ABI可能是上面说过的七种ABI中的一种。
Native Libs Monitor这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数库或者框架。
当然,我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些。
很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新,例如硬件fpu,更多的寄存器,更好的向量化等)。
我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,如果在对应的lib/ABI目录中存在.so文件的话。
App中可能出错的地方
处理.so文件时有一条简单却并不知名的重要法则。
你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。
当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的话,会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支持armeabi-v7a和armeabi)。
其他地方也可能出错
当你引入一个.so文件时,不止影响到CPU架构。我从其他开发者那里可以看到一系列常见的错误,其中最多的是”UnsatisfiedLinkError”,”dlopen: failed”以及其他类型的crash或者低下的性能:
使用android-21平台版本编译的.so文件运行在android-15的设备上
使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。
这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。
混合使用不同C++运行时编译的.so文件
.so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。作为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的C++运行时。
这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。
没有为每个支持的CPU架构提供对应的.so文件
这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。
例如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库:
发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy S6,最终可以发现只有64位目录下的.so文件被安装进手机。
解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置
显示指定支持的ABIs。
最后一点:如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。
将.so文件放在错误的地方
我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:
- Android Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定)
- Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)
- AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)
- 最终APK文件中的lib/ABI目录中
- 通过PackageManager安装后,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。
只提供armeabi架构的.so文件而忽略其他ABIs的
所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,因此似乎移除其他ABIs的.so文件是一个减少APK大小的好技巧。但事实上并不是:这不只影响到函数库的性能和兼容性。
x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。
以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版本的APK可以在build.gradle中如下配置:
Android 模拟器支持运行 ARM 应用,Android 11 系统映像可直接将 ARM 指令转换成 x86 指令
技术编辑:鸣飞转载于谷歌开发者公众号
随着 Android 11 开发者预览版的发布,我们同时也推出了Android 11 系统映像。新的系统映像在执行 ARM 二进制文件方面取得了显著的性能提升。
此前,依赖 ARM 库且无法构建 x86 版本应用的开发者只能使用完整的 ARM 模拟系统映像 (其速度远低于在 x86 设备上运行 x86 系统映像) 或者实体机。Android 11 系统映像能够在不影响整个系统的前提下,直接将 ARM 指令转换成 x86 指令。开发者无需搭建高负载的 ARM 环境即可执行 ARM 二进制文件并进行测试。
全新的 Android 11 (Google API) x86 系统映像支持 ARM 应用二进制接口 (ABI),较旧版本的 Android Oreo 系统映像并不提供该支持
- Android 11 系统映像https://developer.android.goo...
技术细节
我们可能需要结合具体情景来说明这项新技术的重要性,尤其是如果您只使用 Kotlin 或 Java 编程语言来构建应用的话。Kotlin 和 Java 编程语言均在 ART (Android 运行时) 上执行,但 C++ 则与它们不同,Android 应用中的所有 C++ 指令会直接编译为机器指令,也就是说,目标设备的平台架构决定着 C++ 的编译方法。移动手机一般搭载 ARM 处理器,因此,您为应用添加的许多 C++ 依赖项 (例如摄像头条形码扫描库) 仅与 ARM 处理器兼容。在这种情形下,如果您使用基于 x86 处理器的设备进行开发工作,便会遇到应用无法运行的问题。
过去,开发者需要通过模拟器镜系统映像搭建一个完整的 ARM 环境,才能绕过这个限制并在 x86 机器上执行 ARM 应用。但是,把整个系统的 ARM 指令都转换成 x86 指令会造成过高的性能负荷,因此与基于 x86 的系统映像相比,完整的 ARM 系统映像在 x86 宿主机上的运行速度会慢很多,而且它还无法使用 x86 处理器提供的硬件加速和 CPU 虚拟化技术。
全新的Android 11 系统映像与 ARM 兼容,它不仅允许整个系统在本机运行 x86 指令,而且还可以照常使用虚拟化技术。当应用的某个进程需要使用 ARM 二进制代码时,代码仅会在该进程内被转换成 x86 指令,其余进程将继续在 x86 环境内执行,包括 Android 运行时 (ART) 以及其它性能关键库,例如libGLES和libvulkan。除此以外,指令转换器也不会执行低层的硬件特定库,从而避免高成本的内存访问检测和相应的性能影响。在 ARM 公司的协作下,新的模拟器系统映像在本地和持续集成框架内均可运行。
- Android 11 系统映像
https://developer.android.goo... - libGLES https://developer.android.goo...
- libvulkan
https://developer.android.goo...
下一步
如果您之前由于缺乏高性能的 ARM 支持,去选择了实体机而非模拟器,不妨尝试一下Android 11 系统映像。此映像文件目前已随 Android 11 开发者预览版一同开放下载。您可通过 SDK Manager 或者Android Virtual Device Manager将最新版本的系统映像下载至 Android Studio。
使用 Android Virtual Device Manager 创建一个运行 Android 11 的 AVD
- Android 11 系统映像
https://developer.android.goo...
- Android Virtual Device Manager
https://developer.android.goo...
一旦应用在模拟器中成功运行后,请考虑适配 Chrome OS。Chrome OS 同样也支持在 x86 笔记本上执行 ARM 版本的 Android 应用。通过构建适用于 Chrome OS 的应用,您可以挖掘大屏幕设备生态圈所蕴含的海量机遇,让全球更多的用户认识您的应用。
- 适配 Chrome OS
https://developer.android.goo...
这项技术可以帮助更多开发者在 Android 模拟器上进行测试。我们建议开发者同时构建 x86 和 ARM ABI 两个版本的应用,使其在物理设备上拥有最佳的运行性能并吸引尽可能多的用户。接下来,我们计划在多个 API 级别普及这项技术,同时确保它能和实体机一样支持所有测试用例。欢迎大家向我们提交反馈,帮助我们进一步优化这项新技术。
- 提交反馈
https://issuetracker.google.com/issues?q=componentid:192727%20status:open
请注意: ARM - x86 指令转换技术可用于执行 ARM 公司旗下的产品。该技术只可通过 Google API 和 Play Store 系统映像获取,且仅用于在 x86 台式机、笔记本、客户端本地服务器或自购的云环境上进行应用开发和调试。该技术不可在商用托管服务下使用。
Java 是 Oracle 和/或其附属公司的注册商标。
原文链接:在 Android 模拟器上运行 ARM 应用
android手机适配硬件平台:armeabi,armeabi-v7a,arm64-v8a
ABI:应用程序二进制接口,Application Binary Interface。
- armeabi:针对普通的或旧的第五代、第六代ARM处理器。NDK 以前支持 ARMv5 (armeabi) 以及 32 位和 64 位 MIPS,但 NDK r17 已不再支持,极少用于手机可以忽略。
- armeabi-v7a:针对有浮点运算或高级扩展功能的arm v7 cpu,32位ARM设备。第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它。
- arm64-v8a: 第8代、64位ARM处理器。目前主流版本(Google Play上架要求app必须适配arm64-v8a)
兼容性适配:
- 只适配armeabi的APP可以跑在armeabi,x86,x86_64,armeabi-v7a,arm64-v8上。
- 只适配armeabi-v7a可以运行在armeabi-v7a和arm64-v8a。
- 只适配arm64-v8a 可以运行在arm64-v8a上。
注意: 当v8的手机运行只适配v7的app时,首先会去v8的文件夹下找相应的so文件,存在就直接使用,不存在就会去v7文件夹下找,再者去armeabi文件夹;如果v8的文件夹存在,但是这个文件夹下没有对应的so文件就会报错,所以如果添加一些第三方sdk,注意so文件的类型,不要产生不全的文件夹。
举例:QQ为了适配更多机型,采用仅适配armeabi的方式,保证最大的兼容性!可以与v7、v8的手机兼容,虽然在v7、v8的手机上会有一些性能的消耗。
关于如何在 android x86_64 中运行 arm v8a 应用程序的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于11 是 ISO c++ 下 x86_64、arm 或其他架构的有效输出吗?、Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题、Android 模拟器支持运行 ARM 应用,Android 11 系统映像可直接将 ARM 指令转换成 x86 指令、android手机适配硬件平台:armeabi,armeabi-v7a,arm64-v8a等相关知识的信息别忘了在本站进行查找喔。
本文标签: