我可以的Dalvik和Android工具链得到哪些优化? [英] What optimizations can I expect from Dalvik and the Android toolchain?

查看:165
本文介绍了我可以的Dalvik和Android工具链得到哪些优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的高性能Android应用程序(游戏),虽然我尝试code以增强可读性第一,我想保持在我的脑海里正在发生的事情在一张照片油烟机。用C ++,我开发什么,编译器将并不会为我做一个相当不错的直觉。我想对Java / Android的做同样的。

I'm working on a high-performance Android application (a game), and though I try to code for readability first, I like to keep in the back of my mind a picture of what is happening under the hood. With C++, I've developed a fairly good intuition about what the compiler will and won't do for me. I'm trying to do the same for Java/Android.

因此​​这个问题。我能找到的很少在网络上这个话题。将Java编译器,Dalvik的转换器(DX)和/或抖动(在Android 2.2+)执行优化像下面这样?

Hence this question. I could find very little about this topic on the web. Will the Java compiler, Dalvik converter (dx) and/or JITter (on Android 2.2+) perform optimizations like the following?

  • 方法内联。在什么样的条件? 私人方法可以随时安全地内联;将这样做吗?如何公众最终的方法呢?其他类的对象的方法呢? 静态的方法呢?如果什么对象的运行时类型可以容易地推断出由编译器?我应申报方式为最后静态在可能的情况?

  • Method inlining. Under what conditions? private methods can always safely be inlined; will this be done? How about public final methods? Methods on objects of other classes? static methods? What if the runtime type of the object can easily be deduced by the compiler? Should I declare methods as final or static wherever possible?

常见SUBEX pression消除。举例来说,如果我访问 someObject.someField 键两次,将查找只需要做一次?如果它是调用一个getter?如果我使用了一些算术EX pression两次;将它只计算一次?如果我用了一些前pression,其价值我知道不能改变结果,因为上界循环?

Common subexpression elimination. For example, if I access someObject.someField twice, will the lookup be done only once? What if it's a call to a getter? What if I use some arithmetic expression twice; will it be evaluated only once? What if I use the result of some expression, whose value I know not to change, as the upper bound of a for loop?

边界检查数组查找。请问工具链消除这种在一定条件下,像原型循环?

Bounds checking on array lookups. Will the toolchain eliminate this in certain conditions, like the archetypical for loop?

值内联。将访问一些公共静态最终诠释总是被内联?即使他们在另一个类?即使他们在另一个包?

Value inlining. Will accesses to some public static final int always be inlined? Even if they're in another class? Even if they're in another package?

科prediction。有一个很大的问题,这是什?是分支的大型演出打了一个典型的Andr​​oid设备上?

Branch prediction. How big an issue is this even? Is branching a large performance hit on a typical Android device?

简单的算术。请问 someInt * 2 someInt&LT更换;< 1

等耳熟能详的乐曲......

Etcetera...

推荐答案

这是本,让工程人员对JIT @谷歌之一。当比尔和我开始在这个项目上,我们的目标是尽快与影响最小的资源争提供了一个工作JIT(如内存占用,CPU由编译器线程劫持),以便它可以在低端设备的运行井。因此,我们用了一个很原始的跟踪为主的模式。即,传递给JIT编译器编译实体是一个基本块,有时短为单个指令。这样的痕迹将通过一种被称为链接,使跨preTER和code缓存查找不会经常被缝合在一起运行。在一定程度上加速的主要来源是消除重复跨preTER上频繁执行code路径解析开销。

This is Ben, one of the engineers working on the JIT @ Google. When Bill and I started on this project, the goal was to deliver a working JIT as soon as possible with minimal impact to resource contention (eg memory footprint, CPU hijacked by the compiler thread) so that it can run on low-end devices as well. Therefore we used a very primitive trace based model. That is, the compilation entity passed to the JIT compiler is a basic block, sometimes as short as a single instruction. Such traces will be stitched together at runtime through a technique called chaining so that the interpreter and code cache lookup won't be invoked often. To some degree the major source of speedup comes from eliminating the repeated interpreter parsing overhead on frequently executed code paths.

不过,我们确实有相当的Froyo的JIT实现了一些局部优化:

That said, we do have quite a few local optimizations implemented with the Froyo JIT:

  • 在寄存器分配(8个寄存器用于v5TE的目标,因为JIT生产拇指code / 16寄存器V7)
  • 计划(如冗余LD / ST消除对Dalvik的寄存器,负荷提升,存储下沉)
  • 冗余空检查消除(如果这种冗余可以在一个基本块中找到)。
  • 循环的形成和优化,简单的计算循环(即没有副作用退出的循环体)。对于这样的循环,数组访问基于扩展归纳变量进行了优化,使空和范围的检查,在循环序幕才执行。
  • 在每个虚拟调用点一个条目内联缓存瓦特/动态补丁在运行时。
  • 在窥孔优化像字面操作数MUL / DIV降低功耗。

在姜饼我们添加简单的内联的getter / setter方法​​。因为底层JIT前端仍然是基于简单的痕迹,如果被叫方有分公司,在那里它不会被内联。但是,内联缓存机制的实现,使虚拟的getter / setter方法​​可以毫无问题内联。

In Gingerbread we added simple inlining for getters/setters. Since the underlying JIT frontend is still simple trace based, if the callee has branches in there it won't be inlined. But the inline cache mechanism is implemented so that virtual getters/setters can be inlined without problems.

我们目前正在扩大编制的范围超出了简单的跟踪,使编译器为code分析和优化一个更大的窗口。敬请关注。

We are currently working on enlarging the compilation scope beyond a simple trace so that the compiler has a larger window for code analysis and optimization. Stay tuned.

这篇关于我可以的Dalvik和Android工具链得到哪些优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆