大理石在哪儿
Posted by: Sam Lin, Product Manager, Android
作者:Android产品经理Sam Lin
This is the third in a series of blog posts by the Android Studio team diving into some of the details and behind the scenes of Project Marble. The following post was written by Sam Lin (product manager), Lingfeng Yang (tech lead), and Bo Hu (tech lead) on the Emulator team.
这是Android Studio团队撰写的一系列博客文章中的第三篇,深入探讨了Project Marble的一些细节和幕后花絮。 以下帖子由模拟器团队的Lin(产品经理),Yang Lingfeng(技术负责人)和Bo Hu(技术负责人)撰写。
Today we are excited to give you an update on the progress we have made in the Android Emulator during Project Marble. One of the core goals we have is to make the Android Emulator the go-to device for app development. Physical Android devices are great, but we aim to add features and performance that make you even more efficient when developing and testing your Android apps.
今天,我们很高兴为您提供Project Marble期间我们在Android模拟器中取得的最新进展。 我们的核心目标之一是使Android模拟器成为应用开发的首选设备。 物理Android设备很棒,但我们的目标是添加功能和性能,使您在开发和测试Android应用时更加高效。
We have heard that many app developers like the recent improvements we have made to the emulator, from 2 second start time, GPU graphics acceleration, to snapshots. However, we have also heard that the Android Emulator consumes too many system resources on your development computer. To address this issue, we created an effort in Project Marble to optimize the CPU usage for the Android Emulator. Without deviating from the original design principles, we’ve made significant improvements to the power efficiency and draw rate of the Android Emulator over the last few months during Project Marble. In this post, we will shed some light on the progress we release so far in Android Emulator 28.1 on the canary channel.
我们听说,许多应用程序开发人员都喜欢我们最近对模拟器所做的改进,从2秒的启动时间,GPU图形加速到快照 。 但是,我们还听说Android模拟器消耗了开发计算机上过多的系统资源。 为了解决此问题,我们在Project Marble中进行了努力,以优化Android模拟器的CPU使用率。 在不偏离原始设计原则的情况下,我们在Project Marble的过去几个月中对Android模拟器的电源效率和绘制速率进行了重大改进。 在本文中,我们将阐明到目前为止在canary频道上的 Android Emulator 28.1中发布的进度。
在减少开销的同时保留设计原则 (Preserving Design Principles While Reducing Overhead)
The main benefit of the Android Emulator is to provide developers a scalable way to test the latest Android APIs across a variety of device configurations and screen resolutions, without buying physical devices for every configuration. As such, testing apps on Android Emulator should be as close as possible as testing on a physical device, while keeping the benefits of virtual devices.
Android Emulator的主要好处是为开发人员提供了一种可扩展的方法,可以在各种设备配置和屏幕分辨率下测试最新的Android API,而无需为每种配置购买物理设备。 因此,在保持虚拟设备的优势的同时,在Android Emulator上测试应用程序应与在物理设备上测试尽可能接近。
In order to support the latest system images as soon as they are developed, we intentionally decided to design Android Emulator to be as close to a physical device as possible, as an emulator not a simulator. This approach ensures API correctness and high fidelity of Android system behaviors and interaction. When a new Android version comes out, we only need to ensure that our hardware abstraction layers (HALs) and kernel are compatible with the emulator and new system images, rather than have to re-implement all changes in the Android API for the new Android version from scratch ourselves. The net result of this architecture is that it greatly speeds up adoption of new system images for emulators.
为了尽快支持最新的系统映像,我们有意决定将Android Emulator设计为尽可能接近物理设备,而不是模拟器。 此方法可确保API正确性以及Android系统行为和交互的高保真度。 当出现新的Android版本时,我们只需要确保我们的硬件抽象层(HAL)和内核与仿真器和新的系统映像兼容,而不必为新的Android重新实现Android API中的所有更改版本从头开始。 这种体系结构的最终结果是,它极大地加快了模拟器新系统映像的采用。
However, such a full system emulation approach imposes overhead in both CPU cycles and memory access. In contrast, a simulator based approach would wrap analogous APIs on the host system with possibly less overhead. Therefore, our challenge is to preserve the accuracy and maintenance benefits of full system emulation while reducing the CPU and memory overhead.
但是,这种完整的系统仿真方法在CPU周期和内存访问上都产生了开销。 相比之下,基于模拟器的方法将在主机系统上包装类似的API,而开销可能更少。 因此,我们的挑战是保持完整系统仿真的准确性和维护优势,同时减少CPU和内存开销。
研究Android模拟器架构 (Investigation into the Android Emulator Architecture)
The Android Emulator runs the Android operating system in a virtual machine called an Android Virtual Device (AVD). The AVD contains the full Android software stack, and it runs as if it were on a physical device. The high-level architecture diagram is as follows.
Android仿真器在称为Android虚拟设备(AVD)的虚拟机中运行Android操作系统。 AVD包含完整的Android软件堆栈 ,并且就像在物理设备上一样运行。 高层架构图如下。
Since the entire Android OS runs separately from the host OS, running the Android Emulator can cause background activity on the host’s machine even without any user input. After doing some technical investigation, the following tasks were some of the major consumers of CPU cycles when an AVD is idle:
由于整个Android操作系统与主机OS分开运行,因此即使没有任何用户输入,运行Android仿真器也可能导致主机计算机上的后台活动。 经过一些技术调查后,以下任务是AVD空闲时CPU周期的主要消耗者:
- Google Play Store — app updates happen automatically when new versions are available. Google Play商店-当有新版本可用时,应用程序更新会自动发生。
- Background services — several on-demand services kept the CPU usage high when it assume the device was charging. 后台服务-假设设备正在充电,一些按需服务使CPU使用率很高。
Animations — such as Live wallpapers.
动画-例如动态壁纸 。
For these areas we did a deep set of technical investigations and landed on the following top five solutions to optimize the Android Emulator.
对于这些领域,我们进行了深入的技术研究,并采用以下五个最佳解决方案来优化Android模拟器。
- Battery mode by default 默认为电池模式
- Emulator pause/resume 仿真器暂停/恢复
- Draw call overhead reduction 减少通话费用
- macOS main loop IO overhead reduction macOS主循环IO开销减少
- Headless Build 无头打造
改进#1-默认情况下为电池模式 (Improvement #1 — Battery mode by default)
Previously, the Android Emulator set the AVD’s battery charging mode to be on AC power. After thoughtful discussions and data analysis, we concluded that it is best to set an AVD on battery mode by default. This is because most of the Android framework, services and apps are optimized to save battery life, and these optimizations only kick in if the device (either physical or virtual) thinks it’s using the battery rather than charging off AC power.
以前,Android仿真器将AVD的电池充电模式设置为交流电源 。 经过认真的讨论和数据分析,我们得出的结论是,最好将AVD默认设置为电池模式。 这是因为大多数Android框架,服务和应用程序都经过优化以节省电池寿命,并且只有在设备(物理或虚拟)认为其正在使用电池而不是为交流电源充电时才启动这些优化。
However, it’s not enough to just default the AVD to use battery. That’s because being on battery mode also causes the screen to turn off automatically after a period of time. This can be confusing to users who are using the emulator on laptops or desktop, where there is an expectation that apps don’t randomly go to sleep and need to be woken up. To avoid this condition, Android Emulator will set screen off timeout using an ADB shell command to the maximum (~24 days) at each cold boot complete.
但是,仅将AVD默认使用电池是不够的。 这是因为处于电池模式还会导致屏幕在一段时间后自动关闭。 这可能会使在笔记本电脑或台式机上使用仿真器的用户感到困惑,因为他们期望应用程序不会随机进入睡眠状态,而需要被唤醒。 为了避免这种情况,Android Emulator将在每次冷启动完成时使用ADB shell命令将屏幕关闭超时设置为最大(〜24天)。
With these changes, Google Play Store will not update apps automatically on the battery mode, and avoid overloading the system. However, the auto-updating of apps can still be triggered by switching back to AC charging mode. This actually gives developers control on when to update apps automatically. Which can prevent interference in critical use cases, such as when the user simply wants to build and test a single app. The following chart compares CPU usage on battery versus on AC power:
进行这些更改后,Google Play商店将不会以电池模式自动更新应用程序,并避免系统过载。 但是,仍然可以通过切换回AC充电模式来触发应用程序的自动更新 。 实际上,这使开发人员可以控制何时自动更新应用程序。 这可以防止在关键用例中产生干扰,例如,当用户仅想构建和测试单个应用程序时。 下表比较了电池和交流电源上的CPU使用率:
改进2 –仿真器暂停/恢复 (Improvement #2 — Emulator pause/resume)
In many cases, you may want an immediate guarantee that the emulator isn’t chewing up CPU cycles in the background during critical tasks such as the edit and build steps of the edit / build / deploy loop. To address this, we’re working on a console command and interface for pausing the emulator’s CPU usage completely. This can be accomplished by following console commands to pause/resume the AVD explicitly.
在许多情况下,您可能需要立即保证模拟器在关键任务(例如edit / build / deploy循环的edit和build步骤)期间不会在后台消耗CPU周期。 为了解决这个问题,我们正在开发一个控制台命令和界面,以完全暂停模拟器的CPU使用率。 这可以通过遵循控制台命令来显式暂停/恢复AVD来完成。
![Image for post](https://miro.medium.com/max/9999/1*Q77jcfo5jiRqRwhW2l2NgA.png)
The challenge here is how to coordinate this Android Emulator state change with Android Studio. So when an app deploy happens, we auto resume the emulator. We are still working on this mechanism, and happy to hear your thoughts and feedback.
这里的挑战是如何与Android Studio协调此Android Emulator状态更改。 因此,当发生应用部署时,我们会自动恢复模拟器。 我们仍在研究这种机制,很高兴听到您的想法和反馈 。
改进3 –减少通话费用 (Improvement #3 — Draw call overhead reduction)
We’ve also made changes in the Android Emulator engine that make it more efficient at drawing, which results in a smoother user experience when testing graphics-heavy apps with many objects on screen. For example, Emulator v28.1.10 draws 8% faster on GPU emulation stress test app compared with that in v28.0.23. We are also working on further optimizations in Android Q, and will share additional updates during the Android Q preview.
我们还对Android Emulator引擎进行了更改,以使其更有效地进行绘制,从而在测试屏幕上有许多对象的图形繁多的应用程序时,可以带来更流畅的用户体验。 例如,与v28.0.23中的仿真器相比,emulator v28.1.10在GPU仿真压力测试应用程序上绘制速度加快了8%。 我们还将在Android Q中进行进一步的优化,并将在Android Q预览期间共享其他更新。
改进#4-减少macOS主循环IO开销 (Improvement #4 — macOS main loop IO overhead reduction)
A full system emulator must maintain some kind of method to notify the virtual OS that I/O operations on disk & network complete. Android Emulator is based on QEMU, and uses a main loop and iothreads to accomplish this. It has low overhead on Linux and Windows. However on macOS, we have seen higher CPU usage of the main loop due to its usage of the select() system call. Which is often not implemented efficiently. macOS does provide a low overhead method to wait on I/O: kqueue. We’ve found that the main I/O loop, that is currently based on select() can be replaced with a main I/O loop based on kqueue. This greatly decreased the CPU usage of the main loop, from ~10% to ~3%. Since this does not account for all idle CPU usage, the chart (below) does not show much change. Nevertheless, the difference is still observable.
完整的系统模拟器必须维护某种方法,以通知虚拟OS磁盘和网络上的I / O操作完成。 Android Emulator基于QEMU ,并使用主循环和iothreads完成此任务。 它在Linux和Windows上的开销很低。 但是,在macOS上,由于使用了select()系统调用,因此主循环的CPU使用率更高。 这通常无法有效实施。 macOS确实提供了一种低开销的方法来等待I / O: kqueue 。 我们发现,当前基于select()的主I / O循环可以替换为基于kqueue的主I / O循环。 这大大降低了主循环的CPU使用率,从〜10%降低到〜3%。 由于这不能解决所有空闲的CPU使用情况,因此该图表(下图)不会显示太多变化。 尽管如此,差异仍然可以观察到。
改进5 –无头构建 (Improvement #5 — Headless Build)
For those of you using continuous integration systems for your Android app builds, we also worked on performance improvements in this area as well. By turning off the user interface in the Android Emulator, you can use access a new emulator-headless mode. This new mode runs tests in the background and uses less memory. It also takes about 100MB less, mainly because the Qt libraries we use for the user interface are not loaded. This is also a good choice to run automated tests when UI and user interactions are not required. The delta can be measured by starting 2 Emulator AVD instances as follows. Note that, the command line example specifies host GPU mode explicitly to ensure the comparison is under the same conditions.
对于使用持续集成系统构建Android应用程序的用户,我们也在该领域进行了性能改进。 通过关闭Android模拟器中的用户界面,您可以使用访问新的无头模拟器模式。 此新模式在后台运行测试,并使用较少的内存。 它还节省了约100MB的空间,这主要是因为未加载用于用户界面的Qt库。 当不需要UI和用户交互时,这也是运行自动化测试的不错选择。 可以通过如下启动2个Emulator AVD实例来测量增量。 请注意,命令行示例明确指定了主机GPU模式,以确保在相同条件下进行比较。
![Image for post](https://miro.medium.com/max/9999/1*qhp25FXwP_K4gE8ggOQQbQ.png)
下一步 (Next Steps)
To use the performance and resource optimization covered in this blog, download Android Emulator 28.1 available today on the canary channel. We are excited to share this early checkin-in on the progress with you, but we are definitely not done yet. We invite you to try the latest updates of Android Emulator today, and send us your feedback.
要使用此博客中介绍的性能和资源优化,请在canary频道上下载今天可用的Android Emulator 28.1。 我们很高兴与您分享此进度的早期签到,但我们肯定还没有完成。 我们邀请您今天尝试Android Emulator的最新更新,并将您的反馈发送给我们。
翻译自: https://medium.com/androiddevelopers/android-emulator-project-marble-improvements-1175a934941e
大理石在哪儿