12

When I use TOP command, I could get the following info:

shell@android:/ $ top -n 1                                                     

User 31%, System 10%, IOW 0%, IRQ 0%
User 346 + Nice 10 + Sys 120 + Idle 637 + IOW 6 + IRQ 0 + SIRQ 2 = 1121

  PID PR CPU% S  #THR     VSS     RSS PCY UID      Name
  481  1  26% S    89 762832K  81688K  fg system   system_server
 1699  0   5% S    27 676472K  39092K  fg u0_a72   wm.cs.systemmonitor
11243  0   3% S    28 673140K  29796K  bg u0_a111  com.weather.Weather
13327  2   1% S    23 680472K  35844K  bg u0_a83   com.rhmsoft.fm
  659  0   1% S    17 663044K  33136K  bg u0_a13   android.process.media
20260  1   0% R     1   1208K    508K     shell    top

We can see the CPU% is round to integer, is there any way I could get a process's CPU% with higher precision?

-- Clarifications on the bounty -- Alex

The question refers to Android system, and preferably to a non-rooted device. While Android provides advanced profiling techniques for Java applications, tools for native code (C++) are limited. top command on Android allows to show the statistics for all threads running in the system, both Java threads and C++ threads. I am looking for an answer that will help with the following quest:

My app uses 2% CPU when it is inactive in background, while it should be below 0.1%. If I run top -t, I get 0% for all 15 threads that belong to my process (some threads are Java threads, e.g. the Main, UI thread; others are pthreads that never attach to JVM). How can I guess which thread eats the battery?

I would be glad to get even more details about this unexpected activity, and Android provides great helpers like TraceView for Java threads. Any insight regarding tools for native code will be highly appreciated.

Community
  • 1
  • 1
JackWM
  • 10,085
  • 22
  • 65
  • 92
  • 2
    wouldn't make much difference.... – Mitch Wheat Mar 01 '13 at 00:19
  • 1
    @MitchWheat: Yes it does make difference. Otherwise, please help me profile the application that uses 2% CPU in background. When I run `top -t`, I get 0% for all 15 threads that belong to my process. How can I guess which thread eats the battery? – Alex Cohn Jun 27 '13 at 07:42
  • I didn't say it wouldn't make any difference; I said "wouldn't make much difference" – Mitch Wheat Jun 27 '13 at 07:49
  • Mitch is right. You may not really need the precision. What if 10 of 15 have 0.0% CPU usage. Most of the time that is the case with background processes. <1% is good enough for ignoring the non-CPU intensive processes. – user568109 Jun 27 '13 at 11:49
  • 1
    user568109: of 15 threads, all show 0%. But together they give quite significant 2%. Some threads are Java, and there are SDK tools to monitor their behavior. Others are C++, and I wanted to get from a simple `top` command enough hibts to help me find the 2 that are responsible for most consumption. – Alex Cohn Jun 27 '13 at 18:38
  • I won't post because I don't have a way to test, but you should be able to get raw information about each thread's cpu use in _clock ticks_ in `/proc/[pid]/task/[thread name]`. That's as accurate as you'll be able to get. See `http://man7.org/linux/man-pages/man5/proc.5.html`. – Gene Jun 29 '13 at 21:08
  • "How can I guess which thread eats the battery?" -- um, wouldn't it be the thread that's not blocking very long (e.g., polling, busy-waiting)? Isn't this a matter of code review, more so than tooling? – CommonsWare Jun 30 '13 at 20:50
  • 1
    @CommonsWare: definitely, this is a bug in my app. But a full code review that would resolve the issue is beyond my capabilities. If I could concentrate on one thread, it would become possible. – Alex Cohn Jul 01 '13 at 07:15
  • 1
    @Gene: please provide an Answer with the content of your comment, it deserves the bounty. The command line is `adb shell cat /proc/${pid}/task/*/stat | awk -F\ '{print $1, $14}'` (note that awk runs on the host). – Alex Cohn Jul 01 '13 at 07:20
  • @AlexCohn Okay thanks. I did post an article. It works on my machine, too. – Gene Jul 01 '13 at 13:24

4 Answers4

6

You didn't mention it in your post, but in the comment you said that you really need CPU utilization per thread, not per process.

If you can't find a tool that's accurate enough, you can look directly in /proc/[pid]/task/[ThreadName] as described in the man page for /proc. This gives total CPU time consumed in "clock ticks" since execution began. Getting better resolution than this is probably difficult or impossible.

Edit

From the OP's comment, a command that lists the relevant information is:

adb shell cat /proc/${pid}/task/*/stat | awk -F\ '{print $1, $14}' 

This just cats the correct /proc files to the debugging host, which runs a tiny awk program to print the columns for pid and user time. You could also easily use cut -d " " -f1,14 or something similar in perl to get the columns if awk isn't available.

Gene
  • 46,253
  • 4
  • 58
  • 96
  • 3
    On *some* devices, you can also get at the schedstat counters (`/proc//schedstat` and `/proc//task//schedstat`). The three fields are: time spent on the CPU; time spent waiting on a runqueue; # of timeslices run on the CPU. Some OEMs don't enable this feature in the kernel though. – fadden Jul 09 '13 at 16:57
3

Try this:

ps -eo pcpu,pid,user,args | sort -r -k1 | less 

%CPU   PID USER     COMMAND
 9.0  2721 user   bash
 1.4   956 root     ...
 0.5  2212 user   ...

EDIT:

You can use adb shell and busybox (http://www.busybox.net/downloads/BusyBox.html)

adb shell busybox top

c:\ adb push busybox /system/bin
c:\ adb shell
# busybox top 

CPU:  2.3% usr  3.1% sys  3.9% nic 90.5% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 1.06 1.66 10.63 1/589 8048
←[7m  PID  PPID USER     STAT   VSZ %MEM CPU %CPU COMMAND←[0m
31619  2180 10112    S     217m 67.0   0  3.8 com.mgeek.android.DolphinBrowser.B

 2232  2180 1000     S     551m169.6   0  2.6 system_server
 8038  8037 0        R     2068  0.6   0  0.8 busybox top
 2178     1 0        S    11092  3.3   0  0.6 /system/bin/drexe
 6812  2180 10104    S     199m 61.2   0  0.5 android.tether
 2291  2180 1001     S     324m 99.8   0  0.3 com.android.phone
 2308  2180 10006    S     325m100.0   0  0.1 com.sec.android.app.dialertab
 2177     1 1001     S     9624  2.8   0  0.1 /system/bin/rild
    5     2 0        SW<      0  0.0   0  0.1 [events/0]
30087  2180 10022    S     358m110.4   0  0.0 com.samsung.vvm
 2304  2180 10006    S     311m 96.0   0  0.0 com.sec.android.app.twlauncher
16110  2180 10006    S     296m 91.3   0  0.0 android.process.acore
 2445  2180 10006    S     272m 83.8   0  0.0 com.sec.android.provider.logsprovi

 8064  2180 10002    S     238m 73.4   0  0.0 com.google.process.gapps
31537  2180 10037    S     227m 69.9   0  0.0 com.google.android.gm
 2288  2180 10048    S     221m 68.1   0  0.0 com.swype.android.inputmethod
 2285  2180 10013    S     215m 66.3   0  0.0 com.tat.livewallpaper.aurora
30664  2180 10011    S     213m 65.8   0  0.0 com.android.email
31191  2180 10099    S     209m 64.4   0  0.0 com.sirma.mobile.bible.android
 2377  2180 10087    S     207m 63.9   0  0.0 android.tts

(Taken from here)

Alberto Megía
  • 2,225
  • 3
  • 23
  • 33
2

Got this information from another thread:

3) Getting CPU info

~$ adb shell dumpsys cpuinfo

Output:

Load: 0.08 / 0.4 / 0.64 CPU usage from 42816ms to 34683ms ago: system_server: 1% = 1% user + 0% kernel / faults: 16 minor kdebuglog.sh: 0% = 0% user + 0% kernel / faults: 160 minor tiwlan_wq: 0% = 0% user + 0% kernel usb_mass_storag: 0% = 0% user + 0% kernel pvr_workqueue: 0% = 0% user + 0% kernel +sleep: 0% = 0% user + 0% kernel +sleep: 0% = 0% user + 0% kernel TOTAL: 6% = 1% user + 3% kernel + 0% irq

EDIT:

You can also try this command: echo $(adb shell ps | grep com.android.phone | awk '{ system("adb shell cat /proc/" $2 "/stat");}' | awk '{print $14+$15;}')

Also:

using top : This will show you the cpu stats top -b -n 1 |grep ^Cpu

using ps: This will show you the % cpu usage for each process. ps -eo pcpu,pid,user,args | sort -r -k1 | less

EDIT2:

In realtion to your comments and the bounty description (How can I guess which thread eats the battery?) I found an interesting page:

http://ziyang.eecs.umich.edu/projects/powertutor/

As stated there:

You can use PowerTutor to monitor the power consumption of any application.

Try this for an instance and see if it meets your requirements.

FINAL EDIT:

Check out the Systrace documentation on the developer.android.com site:

http://developer.android.com/tools/debugging/systrace.html http://developer.android.com/tools/help/systrace.html

I'm sorry if you already tried that, but that's one concrete method to measure the performance.

Community
  • 1
  • 1
g00dy
  • 6,752
  • 2
  • 30
  • 43
  • As I explained in the bounty description, higher precisionCPU usage is interesting when used together with -t parameter, to help find the thrrads that are not idle enough. – Alex Cohn Jun 27 '13 at 18:43
  • BTW, `ps` on my devices does not support `-eo`. – Alex Cohn Jun 27 '13 at 18:45
  • re: PowerTutor - it does not provide per-thread resolution. But it definitely gives a lot of useful information, e.g. Wi-Fi or display power consumption per application. – Alex Cohn Jul 01 '13 at 07:52
  • re: systrace. I am glad you mentioned it here, because we should be reminded again and again about the powerful profiling tools available for Android JVM. Unfortunately, it does not provide information on native pthreads. – Alex Cohn Jul 01 '13 at 07:56
-2

Use DDMS and method profiling to get a TraceView.

Basically:

  1. Launch your app in debug mode
  2. In DDMS, in the Devices tab, click "Start method profiling"
  3. Do stuff on your device to recreate the conditions you want to monitor
  4. Click "Stop method profiling"
  5. You'll get a fairly detailed graph with each thread's execution that you can drill down into

More details here: http://developer.android.com/tools/debugging/debugging-tracing.html

Disclaimer: I've only done this with a simple test app so I don't know how much mileage you'll get out of it. It does seem to give a bit more precision than what has been described so far, and does not require root.

enter image description here

Ken Wolf
  • 23,133
  • 6
  • 63
  • 84
  • 1
    The approach you published here is definitely useful in many cases, and we should be reminded again and again about the powerful profiling tools available for Android JVM. Unfortunately, this does not answer the question, because the stumbling block is the native threads activity - which is not covered by TraceView. – Alex Cohn Jul 01 '13 at 07:23