-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Android battery drain measurement #522
Comments
This looks like it could be interesting to investigate. |
I believe that, on some devices at least, battery status may already be exposed via sysfs and can be collected via existing instrumentation. However, it may be worth adding a probe that uses the standard Android API as a more portable solution... |
Sorry I should have mentioned the goal of why I'm requesting this too! The idea is that being able to use WorkloadAutomation to run performance test on Android devices and use this interface to collect power measurements to see the impact. Ultimately helping us do A/B comparison after a code change. Since instrumenting the device for power measurement is not easy, using this API hopefully can give us something generic to work with over a bigger range of devices/platforms. |
Looking into this a bit more it seems the simplest way to get basic battery stats from the system would be via
Would these, or a subset of, metrics be sufficient for your usecase? I'm also wondering if this is to be used for A/B comparison, would you expect to ensure the device had the same starting state and then to take a reading at the start of a job and again at the end of the run comparing the decrease in battery power? |
I need to revisit the dumpsys battery. But it's not what I'm after here. If you try an app like Battery Charging Monitor: https://play.google.com/store/apps/details?id=com.tofabd.batteryanalyzer&hl=en_GB&gl=US You'll see that it gives real time reading of the current drawn from the battery. So my idea was to reset the counter, start an experiment and dump the collected samples of current in experiment A. Then modify the code and re-run experiment B. If my modification in experiment B saves power, the Sum of current samples in B should be smaller than A. One issue is when the USB cable is connected, it has to be set not to charge. Though it's not a requirement. I ran an experiment of running Geekbench when it's charging and I think it should be usable. Ie: when USB is not charing I see the current in the negative ~ -500uA. When it is charging it is at ~ +1250uA then drops to ~ +700uA when Geekbench is running. So we can observe the difference. In my example, if the device is charging then the Sum of Exp. B should be higher to indicate power save (it has charged the battery more than Exp. A). If we can disable charging when running a test that'd be better but I need to look up how feasible is this. Hopefully this makes sense? |
I think that this will be a requirement to be able to get comparable readings as the level of the battery can greatly affect the amount of current being drawn, if the battery is nearly empty you are likely to obtain much larger values that if running with the battery nearly full and this could greatly skew the results. I would interested to see if you repeated your test at differing charge levels whether this would be shown via the application? On this topic I have found there are some applications that attempt to control the charging behavior however it looks like this is not standardised and they attempt to do this by maintaining a list of common nodes exposed via sysfs. E.g. from: https://github.com/sriharshaarangi/BatteryChargeLimit/blob/ff7360c6048475f1843628c6d47a79313e87f6af/app/src/main/res/raw/control_files.json
I see, I think I understand your aim better now thanks. I had a look at similar application "Ampere" to see how they were managing to read the current value and again it looks like they are attempting to file and read the value as exposed via sysfs.
I tried printing these properties out from the API on my nexus 5 and received the following values:
The "current energy" value looked it matches what was reported by the sysfs node but the others look like garbage values so I'm not sure how reliable these would be on other devices and the documentation only seems to talk about nexus devices. Although as the applications I found are still relying on sysfs rather than using the android API I wonder if that could be an indication... So overall it seems to me that the aim here to try and minimise additional influences would be to ensure that battery charging was disabled, and then to sample the reported voltage and current values (via some mechanism) to estimate the amount of energy consumed over the an amount of time. I suspect these reading may still be rather inaccurate compared to hardware instrumentation however it might be enough to provide A/B comparisons for multiple runs on the same device. Does that seem reasonable? |
Please don't gate this on the ability to stop USB charging. There are many ways of avoiding them, one of them is just with adb over wifi. Let's limit the scope of this to just battery draining. The documentation can include a warning about the battery not being charged while using the instrument. |
As Javi already pointed out, the USB issue isn't a show stopper. I will try to schedule an experiment next week to see how current reading would differ depending on battery charge. Accuracy can be an issue but I think the limitation it will impose is on the length of the experiment one can conduct only. If each experiments take few mins I'd expected A/B comparison to be fairly representative. But if each one takes 2 hours, then a total run time of 4 hours could be suffering from the accuracy problems, yes. I will try to collect some data.
If the API is not reliable that would be a bummer actually. I thought these apps are using it :-/
Yes. In a lot of cases it'll help doing more tests and measurements on desk without special instrumentation; especially in the WFH environment we're in now. IMO it should be good enough to run 10 mins test for experiment A, then flash new kernel and run experiment B for another 10 mins and see if things are any better. |
I've put together a WIP instrument to try and help with this investigation [1] [2]. It aims to search for a valid sysfs node for current readings and polls this along with The instrument will save it's raw readings in the workload directory and adds a summary with the derived energy metrics to estimated the total energy and average battery power. At it's very best the outputs looks something like the following. The jobs are 30 seconds each, have battery charging manually disabled and uses a fixed delay of 30 seconds between each job to try and allow time for the readings to update between each job.
As can be seen, the results for the same workload appear to vary hugely so it looks like this still requires further digging to see if these readings would be able to produce any useful results. Please let me know what behavior you observe in your experiments. [1] ARM-software/workload-automation#1159 |
Thanks a lot Marc. I was expecting to get current readings. Next week I will dedicate more time to run experiments on Pixel 4 and report back. |
Ok great thanks. Just FYI the raw readings are saved in the job directory to inspect directly, an example is show below with the output normalized using the provided scaling factors.
|
Sorry for the delayed response. I grabbed your PRs and managed to have a run on Pixel 4 using hackbench. I did 10 runs without a delay between the runs.
|
I think the numbers look sane. I just found 1 second minimum sampling time is too coarse, no? I did run some experiments with hackbench and reading current_avg from sysfs and the numbers looked sane to me. I used both 10ms and 100ms in that case as I was running a script on the target. Not sure in your case you issue a adb command every 1second or you run something on the target. The latter might be more reliable. I was talking to the device via TCP by the way. |
On my device I found that the raw values only updated every 3 or 4 seconds, were you able to obtain more precise data from you device?
Interesting, do you have a comparisons set of runs using an idle workload to compare the difference?
Yes the current implementation polls with an adb command which I agree is not ideal, for the proper implementation it would definitely be better to run purely on the device similar to how the file poller operates. |
Yes, using my own script I collected data using 10ms and 100ms sampling rate. The 10ms caused the baseline power to be higher since more work is done in the background. This picture is from 5 runs of hackbench with 15 seconds between each run. Note that each run is collected independently and aggregated at the end, hence the slope between each run The below is a capture when the device is idle. Note in both tests I hold /sys/power/wake_lock otherwise deep sleep causes issues. I certainly had less variations in the past compared to this run I just captured My script is very simple
|
Thanks for doing those run, they look a lot more promising than what I had on my device, although I guess that could also be down to the age difference in devices. Did you have a chance to test out the instrument in the PR's to see if the methodology there is valid and whether that something that would be of use? Or are you looking for something more low level for your own processing? |
Yes I did. The result in #522 (comment) are from your PRs. I used my own script to see how usable it is to do ms granularity sampling only. If I could have done that with your PR then sorry I missed it. The goal is really to be able to use that in absence of proper hardware instrumentation. I admit my experience of setting up wa with hardware instrumentation is close to none. But assuming there's a standard output from using acme cape or monsoon for instance, it'd be good if battery_mon produces similar output so that other tools built on top can transparently use it. I'm thinking mainly wltests in LISA. https://github.com/ARM-software/lisa/tree/master/tools/wltests Generally with this approach I can think of 2 potential limitations:
For 2, imagine I have improved the code such that it will allow the device to spend more time in deeper idle state, then the measurement noise could interfere with the ability to detect this. We might be able to mitigate against that if we ensure the poller script/instrument is attached to "Background" cgroup. This might reduce its impact since they are limited with the amount of resources they can consume. Thinking out loudly mostly :-) |
Ah right yes that makes sense, no I hadn't expected that granularity to work, so that is something I can modify to allow.
We have a standard instrument output format in the form of a MeasurementsCSV which the PR should adhere to and is what allows the DerivedEnergy instrument to operate on the collected output. Although thanks for mentioning wltests, I'm not familiar with what they're expecting so will take a look.
Agreed, and by the looks of it, it seems that it would vary largely depending on the particular device in question.
Yes that is a good point, I think the overhead is going to be the other limitation of this approach, it certainly requires more thought but I guess the first step would be optimize this approach to minimize it's footprint. |
I got a pixel 5 setup now too. I had a hackbench run with your PR but the numbers look wrong to me :-/ I have tried with my script wtih 100ms sampling rate, it looks okay(ish) but the implementation of /sys/class/power_supply/battery/current_avg is not as good as in pixel 4. The value is only updated at fixed intervals Note that on pixel 5 the sysfs returns negative value compared to a positive value on p4. I did all my runs without usb cable plugged, so definitely weren't charging. On pixel 5 /sys/class/power_supply/bms/current_avg returns an identical value to the one read from 'battery' folder but positive. I hope this makes sense. |
In your PR, do you try to use the BatteryService/BatteryManager Java API too or just try to find the best sysfs node to read the values from? Not sure if they're any good by the way, just wondering |
I'm currently just attempting to find the best sysfs node, from my (albeit limited) testing the number reported from both were exactly the same so I thought reading the sysfs node would prevent the requirement for running a separate java application just to call the API. Have you observed any different behavior?
That is interesting how is is reported differently on the same device, however to try and combat this as part of the PR when detecting the node it will invert the value as required so that the value is reported (this currently assumes that the device is discharging when initialization takes place however this could be post processed instead if it is more reliable.)
Thanks for trying these out, and it is a shame to see that the later pixel phone does not appear to provide as good. Also I might be missing the obvious but which numbers are looking out of place to you for the PR chart vs from your script? The voltage seems about right at 4.xV and the current looks to be similar to your script's output (both unfortunately varying quite a bit more compared to your pixel 4 runs) after it has been inverted to provide a positive value, although it does seem to have a higher average value... |
Not not really. And I don't know if it's worth the effort or not to be honest. That API is supposed to go via the HAL, so its implementation will be platform specific. Maybe they just hook it up to the sysfs node.. Who knows. Beside on AOSP builds I don't know if we get proper HAL implementation there either. I doubt it, so it could be a dead end.
Indeed. Pixel 4 reading the current_avg from sysfs seemed to be decent. But on P5 it's not as good. Potentially I might be able to tinker with the source code to make it behave better..
Or it could be me who missed something obvious too :-) I got confused because the current values are hovering around 1. But I looked back at the pixel 4 plot in #522 (comment) and it seems you normalize the values and I got caught out with this. So it's me who missed something here hehe :) Thanks! |
Hi. Just checking if there's any plan to handle this request? |
Hi @qais-yousef, Apologies I have not had time to make much progress on this since the last update, however yes this is still on my todo list to complete the investigation. |
No worries and thanks for the update |
Android provides an interface to access battery counters to measure battery drain
https://source.android.com/devices/tech/power/device
https://perfetto.dev/docs/data-sources/battery-counters
Is it possible for devlib to support this API to help with measuring power consumption of an Android device?
Thanks.
The text was updated successfully, but these errors were encountered: