Skip to content

Commit

Permalink
gather "instantaneous" energy usage readings instead of cumulative
Browse files Browse the repository at this point in the history
  • Loading branch information
armcknight committed Jul 26, 2023
1 parent 23db970 commit 925387e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 22 deletions.
3 changes: 3 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/Tools/SentryBenchmarking.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
*/
@interface SentryPowerReading : NSObject
- (instancetype)initWithError:(NSError **)error;
/** This structure as returned from @c task_info gives the amounts since process/device launch; we
* take the difference between two staggered readings to calculate an "instantaneous" amount. */
@property struct task_power_info_v2 info;
/**
* From @c UIDevice.batteryLevel
Expand Down Expand Up @@ -89,6 +91,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
@interface SentryBenchmarkSample : NSObject
@property uint64_t machTime;
@property NSDictionary<NSString *, SentryThreadBasicInfo *> *threadInfos;
/** */
@property NSArray<NSNumber *> *cpuUsagePerCore;
@property SentryPowerReading *power;
@property SentryScreenReading *device;
Expand Down
75 changes: 53 additions & 22 deletions Samples/iOS-Swift/iOS-Swift/Tools/SentryBenchmarking.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace {
const auto frequencyHz = 10;
const auto intervalNs = 1e9 / frequencyHz;
const auto instantaneousReadingStaggerMs = 75;

uint64_t
machTime(void)
Expand Down Expand Up @@ -88,7 +89,7 @@ processor_info_array_t _Nullable processorInfo(natural_t *numCPUs, NSError **err

// htop sleeps for 75 milliseconds between two samples:
// https://github.com/htop-dev/htop/blob/37d30a3a7d6c96da018c960d6b6bfe11cc718aa8/CommandLine.c#L402-L405
std::this_thread::sleep_for(std::chrono::milliseconds(75));
std::this_thread::sleep_for(std::chrono::milliseconds(instantaneousReadingStaggerMs));

natural_t numCPUsB = 0U;
const auto second = processorInfo(&numCPUsB, error);
Expand Down Expand Up @@ -399,27 +400,34 @@ @implementation SentryPowerReading
- (instancetype)initWithError:(NSError *__autoreleasing _Nullable *)error
{
if ((self = [super init])) {
struct task_power_info_v2 powerInfo;

mach_msg_type_number_t size = TASK_POWER_INFO_V2_COUNT;

task_t task = mach_task_self();
kern_return_t kr = task_info(task, TASK_POWER_INFO_V2, (task_info_t)&powerInfo, &size);
if (kr != KERN_SUCCESS) {
if (error) {
*error = [NSError
errorWithDomain:@"io.sentry.error.benchmarking"
code:1
userInfo:@{
NSLocalizedFailureReasonErrorKey : [NSString
stringWithFormat:
@"Error with task_info(…TASK_POWER_INFO_V2…): %d.", kr]
}];
}
return nil;
}

_info = powerInfo;
const auto first = [self powerInfoWithError:nil];
// same 75 ms sleep like htop as we do for cpu usage per core
std::this_thread::sleep_for(std::chrono::milliseconds(instantaneousReadingStaggerMs));
const auto second = [self powerInfoWithError:nil];

_info = {
{ second.cpu_energy.total_user - first.cpu_energy.total_user,
second.cpu_energy.total_system - first.cpu_energy.total_system,
second.cpu_energy.task_interrupt_wakeups - first.cpu_energy.task_interrupt_wakeups,
second.cpu_energy.task_platform_idle_wakeups
- first.cpu_energy.task_platform_idle_wakeups,
second.cpu_energy.task_timer_wakeups_bin_1
- first.cpu_energy.task_timer_wakeups_bin_1,
second.cpu_energy.task_timer_wakeups_bin_2
- first.cpu_energy.task_timer_wakeups_bin_2 },
{ second.gpu_energy.task_gpu_utilisation - first.gpu_energy.task_gpu_utilisation,
second.gpu_energy.task_gpu_stat_reserved0
- first.gpu_energy.task_gpu_stat_reserved0,
second.gpu_energy.task_gpu_stat_reserved1
- first.gpu_energy.task_gpu_stat_reserved1,
second.gpu_energy.task_gpu_stat_reserved2
- first.gpu_energy.task_gpu_stat_reserved2 },
#if defined(__arm__) || defined(__arm64__)
second.task_energy - first.task_energy,
#endif /* defined(__arm__) || defined(__arm64__) */
second.task_ptime - first.task_ptime,
second.task_pset_switches - first.task_pset_switches,
};

UIDevice *_Nonnull device = UIDevice.currentDevice;
_batteryLevel = device.batteryLevel;
Expand All @@ -432,6 +440,29 @@ - (instancetype)initWithError:(NSError *__autoreleasing _Nullable *)error
return self;
}

- (struct task_power_info_v2)powerInfoWithError:(NSError **)error
{
struct task_power_info_v2 powerInfo;

mach_msg_type_number_t size = TASK_POWER_INFO_V2_COUNT;

task_t task = mach_task_self();
kern_return_t kr = task_info(task, TASK_POWER_INFO_V2, (task_info_t)&powerInfo, &size);
if (kr != KERN_SUCCESS) {
if (error) {
*error = [NSError
errorWithDomain:@"io.sentry.error.benchmarking"
code:1
userInfo:@{
NSLocalizedFailureReasonErrorKey : [NSString
stringWithFormat:@"Error with task_info(…TASK_POWER_INFO_V2…): %d.",
kr]
}];
}
}
return powerInfo;
}

- (uint64_t)totalCPU
{
return _info.cpu_energy.total_system + _info.cpu_energy.total_user;
Expand Down

0 comments on commit 925387e

Please sign in to comment.