typical android cpu split between app and kernel - android

What is the typical split between kernel CPU time and UserMode CPU time on an Android while executing a typical cpu-bound application ?
A typical dual core ARM android phone, while executing a common app, and not waiting for i.o from user or network
Even more helpful, if there is any data on the cpu time split between the usermode portion of system libraries, and time spent inside app actual code
(I realize this is a very subjective question, complicated by the jvm/jit and other functions but any pointers (ha!;) would be helpful.)

Well, it really depends on the application. In an application that is I/O bound, the time will be spent in syscalls like read and write. In an application that is compute bound, the CPU time will be almost all userland. In an application that's RAM bound (doing a lot of manipulation of data in RAM) that CPU will spend most of it's time waiting for RAM because of cache misses (I don't think ARM processors have very large caches).
On the other hand, if your app does a lot of UI stuff, while all of the graphics processing is done in userland, there is still a lot of I/O bound operations waiting for the frame-buffer and input devices.

Related

Heavy CPU analysis while running foreground service

So, I've a Service that is important for applications logic and thus needs to be alive all the time.
First thing is first, I created it as a foreground service.
Whenever user starts to run, Service starts to do a lot of heavy things. It uses FusedLocationAPI different type of sensors and do a lot of different calculations. At this point phone starts to heat up (CPU usage is high). When running stops, heating stops and CPU drops lower.
This makes me think that the main problem is whenever these sensors are used and calculations are made, but there's a lot of possibilities that could cause this and I wanted to understand, how can I deeply analyze batter usage in this case? I read that Battery Historian should be way to go, but the information there is complicated and do not give me much information. How can I use this data to understand which class/runnable/code part is held responsible for the CPU usage? Maybe there's better ways to solve this? Thanks in advance.
Detailed analysis on what's happening using CPU profiler (after suggestion).
Image. Application is opened and few different screens are switch to and from. Nothing special. Phone does not heat up and from CPU analysis everything also looks pretty okay.
2.User starts to run and enter heavy state. The yellow (light green) rectangle shows previously mentioned "important service" that bring important role to application. Called functions does not use too much time of CPU considering the % of whole running trip - which makes me think, I've to look somewhere else..
What I saw is that CPU increases heavily whenever I lock the phone (while service is running. From CPU Bottom Up analysis I cannot understand what is causing the problem (orange rectangle) - looks like a bunch of Android stuff is happening, but it does not give me any clue.
From CPU profiler I do understand that I have a serious problem considering CPU usage, but right now I do not understand what is causing it (which piece of code/class/function). I know for the fact that whenever my important service is created (on app start) I use PARTIAL_WAKE_LOCK to not allow CPU go to sleep and also make service to be alive at all times. As I understand I need to find different solution for this, because CPU drains too much of battery.
How could I found this using only profiler? I now this fact only for code and profiler stack does not tell me much about this (maybe Im not looking at the right place?)
I found out the root cause of high CPU usage.
I did detailed investigation on threads and found out that DefaultDispatcher threads are using A LOT of CPU.
Turns out the has been a bug in Kotlin-Coroutines library and latest version provides fixes. When I did tests I used version 1.3.1, but changing version number to 1.3.3 provided me with big improvements: from 40% usage to 10% CPU usage.

what are the reasons for variance in performance measurement of android app

I want to track the boot time and time for certain operations of my app on android.
I am using the code markers approach to measure time for all the basic operations in my app. I have inserted some code markers at various places in code. I record the system time whenever a code marker is reached. And then I take the time difference between the start and end markers to measure boot time and other operations time.
I get some variance in the milliseconds time every time I measure the time for a scenario. For example if I measure boot time in 10 iterations I get different values in the range 1400 ms to 1600 ms everytime.
Due to this variance in readings, I am not always 100% sure whether my change is impacting the boot time and other operations time.
As far as I know, variance can be due to the following reasons :
CPU frequency scaling by Linux kernel. So I have disabled the scaling and set the scaling_governor to performance.
Resources usage due to other processes executing on the device. I have eliminated this also. I use the stock android OS, without any external apps. And before running the tests I first reboot my device. So everytime I run my test, same set of applications are running on my device.
Different battery levels. I always run my tests when my phone is 100% charged and is plugged in.
Also I take the measurements on a same device every time. I have a dedicated device for this task.
What can be the other reasons for variance in performance measurement?
Is there any better way to measure performance?
App performance can vary for several reasons. For example,
Keeping often-requested data in caches by CPU.
File caching by Dalvik/ART runtime.
Since Android runs multiple processes at the same time. Other processes may be executed in between of execution phases of your program.
Garbage collection may halt the execution at any time to analyze the memory.
Those external factors will affect your time measurements, by stealing away CPU time, tying up I/O channels, etc. You need to average your tests across several runs to try to average out those external factors, and accuracy/precision will suffer as a result. A useful discussion for getting accurate time while measure execution is discussed in Best method to measure execution time in Android?.
Apart from those, the performance can also vary on the app side too. For example,
App initializes a lot of objects in the launch process.
App is doing some heavy operations in Activity lifecycle starting
methods — onCreate(), onStart() or onResume()
Layout is too rich and/or too complicated to measure and draw it for
the first time.
To see how performant are the most common operations like object initialization or Activity lifecycle methods, you can use AndroidDevMetrics
Also check, Using Traceview from Android Studio

High Performance Audio Cracking / Prevent a CPU core from downclocking

This may be very specific, still trying to ask:
I'm founder of Heat Synthesizer, a software music synthesizer for Android. (https://play.google.com/store/apps/details?id=com.nilsschneider.heat.demo)
This app generates audio signals in realtime and needs to do heavy math calculations to do so.
Having seen the talk on Google I/O 2013 about "High Performance Audio on Android" (http://www.youtube.com/watch?v=d3kfEeMZ65c), I was excited to implement it as they suggested, but I keep having problems with crackling.
I have a CPU usage of a single core of about 50% on a Nexus 7 (2012), everything seems to be okay so far. Locking has been reduced to a minimum and most of the code is done lock-free.
Using an app that is called Usemon, I can see that the core I use for processing is used only 50% and is even being downclocked by the kernel because my CPU usage is not high enough.
However, this core speed changes result in crackling of the audio, because the next audio block is not calculated fast enough because my core is underclocked.
Is there any way to prevent a core from changing it's clock frequency?
FWIW, I recommend the use of systrace (docs, explanation, example) for this sort of analysis. On a rooted device you can enable the "freq" tags, which show the clock frequencies of various components. Works best on Android 4.3 and later.
The hackish battery-unfriendly way to deal with this is to start up a second thread that does nothing but spin while your computations are in progress. In theory this shouldn't work (since you're spinning on a different core), but in practice it usually gets the job done. Make sure you verify that the device has multiple cores (Runtime.getRuntime().availableProcessors() or NDK equivalent), as doing this on a single-core device would be bad.
Assuming your computations are performed asynchronously in a separate thread, you can do a bit better by changing the worker thread from a "compute, then wait for work" to a "compute, then poll for work" model. Again, far less efficient battery-wise, but if you never sleep then the kernel will assume you're working hard and needs to keep the core at full speed. Make sure you drop out of polling mode if there isn't any actual work to do (i.e. you hit the end of input).

ARM multi-core penalty for Java programs

I wonder if there is a penalty for running Dalvik+JIT on a multi-core ARM chip vs a single core chip?
E.g., if I disable multi-core support in my Android system build and execute the entire phone with a single CPU core, will I get higher performance when running a single-threaded Java benchmark?
How much is the cost of memory barrier and synchronization on multi-core?
I am asking because I vaugely remember seeing single-threaded benchmark scores from single core phones vs dual core phones. As long as the Mhz is about the same, there is no big difference between the two phones. I had expected a slow down in the dual-core phone ....
The simple answer is "why don't you try it and find out?"
The complex answer is this:
There are costs to doing multicore synchronization but there are also benefits to have multiple cores. You can undoubtedly devise a pathological case where a program suffers from the additional overhead of synchronization primitives such that it is deeply affected by their performance. This is usually due to locking at too deep of a level (inside your fast loop). But in the general case, the fact that the dozen other system programs are able to get CPU time on other cores, as well as the kernel servicing interrupts and IO on them instead of interrupting your process, are likely to greatly overwhelm the penalty incurred by MP synchronization.
In answer to your question, a DSB can take dozens or hundreds of cycles and a DMB is likely more costly. Depending on the implementation exclusive load-store instructions can be very fast or very slow. WFE can consume several microseconds, though it shouldn't be needed if you are not experiencing contention.
Background: http://developer.android.com/training/articles/smp.html
Dalvik built for SMP does have additional overhead. The Java Memory Model requires that certain guarantees be enforced, which means issuing additional memory barriers, particularly when dealing with volatile fields and immutable objects.
Whether or not the added overhead will be noticeable depends on what exactly you're doing and what device you're on, but generally speaking it's unlikely you'll notice it unless you're running a targeted benchmark.
If you build for UP and run Dalvik on a device with multiple cores, you may see flaky behavior -- see the "SMP failure example" appendix in the doc referenced above.

How much cpu usage is too much

I'm almost done with an app and I noticed that it runs at about 6-12% cpu when its in the background. Is this too much? What's a good amount our does it mostly depend on the app?
It does depend on the application. 6-12% CPU would be too much for a software like text editor. But it would not be too much for a web crawler and indexer crawling and indexing the web through 30 threads.
Whether it is too much or not also depends on the nature of other processes running on the system. While 6-12% CPU usage may not be threatening to other processes running on the system, but in case you are running a CPU intensive task say, sorting gigabytes of data that you need very urgently or indexing the web, you would want the CPU usage to go as high as 80% or even more and as a result you wouldn't want to run any other CPU intensive process on the server.
If you are concerned that you may be doing some wasteful operation without realizing it, you may want to use the profiler to see if you are spending too much time in code that you shouldn't. It may also be the case that your app requires 6-12% CPU for what it does, which shouldn't a problem if it's actually putting it to good use.

Categories

Resources