From d29651e39e14d9a6435e3e881f01dbbf507d32c4 Mon Sep 17 00:00:00 2001 From: dehydratedpotato <83843298+dehydratedpotato@users.noreply.github.com> Date: Wed, 31 May 2023 13:56:05 -0700 Subject: [PATCH] Delete SocPowerBuddy directory --- SocPowerBuddy/Makefile | 14 - SocPowerBuddy/output.m | 235 ----------------- SocPowerBuddy/sampler.m | 294 --------------------- SocPowerBuddy/socpwrbud.h | 171 ------------ SocPowerBuddy/socpwrbud.m | 539 -------------------------------------- SocPowerBuddy/static.m | 280 -------------------- 6 files changed, 1533 deletions(-) delete mode 100644 SocPowerBuddy/Makefile delete mode 100644 SocPowerBuddy/output.m delete mode 100644 SocPowerBuddy/sampler.m delete mode 100644 SocPowerBuddy/socpwrbud.h delete mode 100644 SocPowerBuddy/socpwrbud.m delete mode 100644 SocPowerBuddy/static.m diff --git a/SocPowerBuddy/Makefile b/SocPowerBuddy/Makefile deleted file mode 100644 index a36aa61..0000000 --- a/SocPowerBuddy/Makefile +++ /dev/null @@ -1,14 +0,0 @@ - -CC=clang -CFLAGS=-fobjc-arc -funroll-loops -Ofast -arch arm64 -mmacosx-version-min=11.0 -LIBS=-lIOReport -framework Foundation -framework IOKit - -PROGS= socpwrbud - -all: $(PROGS) - -socpwrbud: *.m - $(CC) $(CFLAGS) -o $@ $^ ${LIBS} - -clean: - rm -rf ${PROGS} *.o diff --git a/SocPowerBuddy/output.m b/SocPowerBuddy/output.m deleted file mode 100644 index e0f148f..0000000 --- a/SocPowerBuddy/output.m +++ /dev/null @@ -1,235 +0,0 @@ -/* - * output.m - * SocPowerBuddy - * - * Created by BitesPotatoBacks on 8/5/22. - * Copyright (c) 2022 BitesPotatoBacks. - */ - -#include "socpwrbud.h" - -/* - * Output for plain text - */ -void textOutput(iorep_data* iorep, - static_data* sd, - variating_data* vd, - bool_data* bd, - cmd_data* cmd, - unsigned int current_loop) { - - unsigned int current_core = 0; - - fprintf(cmd->file_out, "%s %s (Sample %d):\n\n", [sd->extra[0] UTF8String], [sd->extra[1] UTF8String], current_loop + 1); - - for (int i = 0; i < [vd->cluster_freqs count]; i++) { - if ((bd->ecpu && [sd->complex_freq_channels[i] rangeOfString:@"ECPU"].location != NSNotFound) || - (bd->pcpu && [sd->complex_freq_channels[i] rangeOfString:@"PCPU"].location != NSNotFound) || - (bd->gpu && [sd->complex_freq_channels[i] rangeOfString:@"GPU"].location != NSNotFound)) { - - char* microarch = "Unknown"; - - if ([sd->complex_freq_channels[i] rangeOfString:@"ECPU"].location != NSNotFound) microarch = (char*)[sd->extra[2] UTF8String]; - else if ([sd->complex_freq_channels[i] rangeOfString:@"PCPU"].location != NSNotFound) microarch = (char*)[sd->extra[3] UTF8String]; - - if ([sd->complex_freq_channels[i] rangeOfString:@"CPU"].location != NSNotFound) { - fprintf(cmd->file_out, "\t%d-Core %s %s:\n\n", [sd->cluster_core_counts[i] intValue], microarch, [sd->complex_freq_channels[i] UTF8String]); - - if (bd->cycles) fprintf(cmd->file_out, "\t\tSupposed Cycles Spent: %ld\n", [vd->cluster_instrcts_clk[i] longValue]); - - /* instructions metrics are only available on CPU clusters */ - if (bd->intstrcts) { - float retired = [vd->cluster_instrcts_ret[i] floatValue]; - - if (retired > 0) { - fprintf(cmd->file_out, "\t\tInstructions Retired: %.5e\n", retired); - fprintf(cmd->file_out, "\t\tInstructions Per-Clock: %.5f\n\n", retired / [vd->cluster_instrcts_clk[i] floatValue]); - } else { - fprintf(cmd->file_out, "\t\tInstructions Retired: 0\n"); - fprintf(cmd->file_out, "\t\tInstructions Per-Clock: 0\n\n"); - } - } - } else - fprintf(cmd->file_out, "\t%d-Core Integrated Graphics:\n\n", sd->gpu_core_count); - - /* - * printing outputs based on tuned cmd args - */ - if (bd->power) fprintf(cmd->file_out, "\t\tPower Consumption: %.2f %s\n", (float)([vd->cluster_pwrs[i] floatValue] * cmd->power_measure), cmd->power_measure_un); - if (bd->volts) fprintf(cmd->file_out, "\n\t\tActive Voltage: %.2f mV\n", [vd->cluster_volts[i] floatValue]); - if (bd->freq) fprintf(cmd->file_out, "\t\tActive Frequency: %g %s\n", (float)(fabs([vd->cluster_freqs[i] floatValue] * cmd->freq_measure)), cmd->freq_measure_un); - if (bd->idle) fprintf(cmd->file_out, "\n"); - if (bd->res) fprintf(cmd->file_out, "\t\tActive Residency: %.1f%%\n", fabs(100-[vd->cluster_use[i] floatValue])); - if (bd->idle) fprintf(cmd->file_out, "\t\tIdle Residency: %.1f%%\n", fabs([vd->cluster_use[i] floatValue])); - - if (bd->dvfm) { - if ([vd->cluster_freqs[i] floatValue] > 0) { - fprintf(cmd->file_out, "\t\tDvfm Distribution: "); - - for (int iii = 0; iii < [sd->dvfm_states[i] count]; iii++) { - float res = [vd->cluster_residencies[i][iii] floatValue]; - - if (res > 0) { - if (!bd->dvfm_volts) { - fprintf(cmd->file_out, "%.fMHz: %.2f%%",[sd->dvfm_states[i][iii] floatValue], res*100); - } else { - fprintf(cmd->file_out, "%.fMHz, %.fmV: %.2f%%",[sd->dvfm_states[i][iii] floatValue], [sd->dvfm_states_voltages[i][iii] floatValue], res*100); - } - - if (bd->dvfm_ms) fprintf(cmd->file_out, " (%.fms)", res * cmd->interval); - fprintf(cmd->file_out, " "); - } - } - fprintf(cmd->file_out, "\n"); - } - } - fprintf(cmd->file_out, "\n"); - - if (i <= ([sd->cluster_core_counts count]-1)) { - for (int ii = 0; ii < [sd->cluster_core_counts[i] intValue]; ii++) { - fprintf(cmd->file_out, "\t\tCore %d:\n", current_core); - - if (bd->power) fprintf(cmd->file_out, "\t\t\tPower Consumption: %.2f %s\n", (float)([vd->core_pwrs[i][ii] floatValue] * cmd->power_measure), cmd->power_measure_un); - if (bd->volts) fprintf(cmd->file_out, "\t\t\tActive Voltage: %.2f mV\n", [vd->core_volts[i][ii] floatValue]); - if (bd->freq) fprintf(cmd->file_out, "\t\t\tActive Frequency: %g %s\n", (float)(fabs([vd->core_freqs[i][ii] floatValue] * cmd->freq_measure)), cmd->freq_measure_un); - if (bd->res) fprintf(cmd->file_out, "\t\t\tActive Residency: %.1f%%\n", (float)(fabs([vd->core_use[i][ii] floatValue]))); - if (bd->idle) fprintf(cmd->file_out, "\t\t\tIdle Residency: %.1f%%\n", (float)(fabs(100-[vd->core_use[i][ii] floatValue]))); - - if (bd->dvfm) { - if ([vd->core_freqs[i][ii] floatValue] > 0) { - fprintf(cmd->file_out, "\t\t\tDvfm Distribution: "); - - for (int iii = 0; iii < [sd->dvfm_states[i] count]; iii++) { - float res = [vd->core_residencies[i][ii][iii] floatValue]; - - if (res > 0) { - if (!bd->dvfm_volts) { - fprintf(cmd->file_out, "%.fMHz: %.2f%%",[sd->dvfm_states[i][iii] floatValue], res*100); - } else { - fprintf(cmd->file_out, "%.fMHz, %.fmV: %.2f%%",[sd->dvfm_states[i][iii] floatValue], [sd->dvfm_states_voltages[i][iii] floatValue], res*100); - } - if (bd->dvfm_ms) fprintf(cmd->file_out, " (%.fms)", res * cmd->interval); - fprintf(cmd->file_out, " "); - } - } - fprintf(cmd->file_out, "\n"); - } else { - fprintf(cmd->file_out, "\t\t\tDvfm Distribution: None\n"); - } - } - - current_core++; - } - fprintf(cmd->file_out, "\n"); - } - } - } -} - -/* - * Output for plist - */ -void plistOutput(iorep_data* iorep, - static_data* sd, - variating_data* vd, - bool_data* bd, - cmd_data* cmd, - unsigned int current_loop) { - - unsigned int current_core = 0; - - fprintf(cmd->file_out, "processor%s\n", [sd->extra[0] UTF8String]); - fprintf(cmd->file_out, "soc_id%s\n", [sd->extra[1] UTF8String]); - fprintf(cmd->file_out, "sample%d\n", current_loop + 1); - - for (int i = 0; i < [vd->cluster_freqs count]; i++) { - if ((bd->ecpu && [sd->complex_freq_channels[i] rangeOfString:@"ECPU"].location != NSNotFound) || - (bd->pcpu && [sd->complex_freq_channels[i] rangeOfString:@"PCPU"].location != NSNotFound) || - (bd->gpu && [sd->complex_freq_channels[i] rangeOfString:@"GPU"].location != NSNotFound)) { - - char* microarch = "Unknown"; - - if ([sd->complex_freq_channels[i] rangeOfString:@"ECPU"].location != NSNotFound) microarch = (char*)[sd->extra[2] UTF8String]; - else if ([sd->complex_freq_channels[i] rangeOfString:@"PCPU"].location != NSNotFound) microarch = (char*)[sd->extra[3] UTF8String]; - - if ([sd->complex_freq_channels[i] rangeOfString:@"CPU"].location != NSNotFound) { - fprintf(cmd->file_out, "%s\n\n", [sd->complex_freq_channels[i] UTF8String]); - fprintf(cmd->file_out, "\tmicroarch%s\n", microarch); - fprintf(cmd->file_out, "\tcore_cnt%d\n", [sd->cluster_core_counts[i] intValue]); - - /* instructions metrics are only available on CPU clusters */ - if (bd->intstrcts) { - float retired = [vd->cluster_instrcts_ret[i] floatValue]; - - if (retired > 0) { - fprintf(cmd->file_out, "\tinstrcts_ret%.f\n", retired); - fprintf(cmd->file_out, "\tinstrcts_per_clk%.5f\n", retired / [vd->cluster_instrcts_clk[i] floatValue]); - } else { - fprintf(cmd->file_out, "\tinstrcts_ret0\n"); - fprintf(cmd->file_out, "\tinstrcts_per_clk0\n"); - } - - fprintf(cmd->file_out, "\tcycles_spent%ld\n", [vd->cluster_instrcts_clk[i] longValue]); - } - } else { - fprintf(cmd->file_out, "\tGPU\n\t\n"); - fprintf(cmd->file_out, "\tcore_cnt%d\n", sd->gpu_core_count); - } - - /* - * printing outputs based on tuned cmd args - */ - if (bd->power) fprintf(cmd->file_out, "\tpower%.2f\n", [vd->cluster_pwrs[i] floatValue]); - if (bd->volts) fprintf(cmd->file_out, "\tmvolts%.f\n", fabs([vd->cluster_volts[i] floatValue])); - if (bd->freq) fprintf(cmd->file_out, "\tfreq%.2f\n", fabs([vd->cluster_freqs[i] floatValue])); - if (bd->res) fprintf(cmd->file_out, "\tactive_res%.2f\n", fabs(100-[vd->cluster_use[i] floatValue])); - if (bd->idle) fprintf(cmd->file_out, "\tidle_res%.2f\n", fabs([vd->cluster_use[i] floatValue])); - - if (bd->dvfm) { - fprintf(cmd->file_out, "\tdvfm_distrib\n\t\n"); - - for (int iii = 0; iii < [sd->dvfm_states[i] count]; iii++) { - fprintf(cmd->file_out, "\t\t%ld\n\t\t\n", [sd->dvfm_states[i][iii] longValue]); - if (bd->dvfm_volts) fprintf(cmd->file_out, "\t\t\tstate_mvolts%.f\n", [sd->dvfm_states_voltages[i][iii] floatValue]); - fprintf(cmd->file_out, "\t\t\tresidency%.2f\n", [vd->cluster_residencies[i][iii] floatValue]*100); - if (bd->dvfm_ms) fprintf(cmd->file_out, "\t\t\ttime_ms%.f\n", [vd->cluster_residencies[i][iii] floatValue] * cmd->interval); - fprintf(cmd->file_out, "\t\t\n"); - } - - fprintf(cmd->file_out, "\t\n"); - } - - if (i <= ([sd->cluster_core_counts count]-1)) { - for (int ii = 0; ii < [sd->cluster_core_counts[i] intValue]; ii++) { - fprintf(cmd->file_out, "\tcore_%d\n\t\n", current_core); - - if (bd->power) fprintf(cmd->file_out, "\t\tpower%.2f\n", [vd->core_pwrs[i][ii] floatValue]); - if (bd->volts) fprintf(cmd->file_out, "\t\tmvolts%.f\n", fabs([vd->core_volts[i][ii] floatValue])); - if (bd->freq) fprintf(cmd->file_out, "\t\tfreq%.2f\n", fabs([vd->core_freqs[i][ii] floatValue])); - if (bd->res) fprintf(cmd->file_out, "\t\tactive_res%.2f\n", fabs([vd->core_use[i][ii] floatValue])); - if (bd->idle) fprintf(cmd->file_out, "\t\tidle_res%.2f\n", fabs(100-[vd->core_use[i][ii] floatValue])); - - if (bd->dvfm) { - fprintf(cmd->file_out, "\t\tdvfm_distrib\n\t\t\n"); - - for (int iii = 0; iii < [sd->dvfm_states[i] count]; iii++) { - fprintf(cmd->file_out, "\t\t\t%ld\n\t\t\t\n", [sd->dvfm_states[i][iii] longValue]); - if (bd->dvfm_volts) fprintf(cmd->file_out, "\t\t\t\tstate_mvolts%.f\n", [sd->dvfm_states_voltages[i][iii] floatValue]); - fprintf(cmd->file_out, "\t\t\t\tresidency%.2f\n", [vd->core_residencies[i][ii][iii] floatValue]*100); - if (bd->dvfm_ms) fprintf(cmd->file_out, "\t\t\t\ttime_ms%.f\n", [vd->core_residencies[i][ii][iii] floatValue] * cmd->interval); - fprintf(cmd->file_out, "\t\t\t\n"); - } - - fprintf(cmd->file_out, "\t\n"); - } - - fprintf(cmd->file_out, "\t\n"); - - current_core++; - } - } - } - - fprintf(cmd->file_out, "\n"); - } -} diff --git a/SocPowerBuddy/sampler.m b/SocPowerBuddy/sampler.m deleted file mode 100644 index a142fcf..0000000 --- a/SocPowerBuddy/sampler.m +++ /dev/null @@ -1,294 +0,0 @@ -/* - * sampler.m - * SocPowerBuddy - * - * Created by BitesPotatoBacks on 7/19/22. - * Copyright (c) 2022 BitesPotatoBacks. - */ - -#include "socpwrbud.h" - -void sample(iorep_data* iorep, // holds our channel subs from the iorep - static_data* sd, // for accessing static data(i.e. core counts, cluster counts, etc) - variating_data* vd, // for get/setting variating data (i.e. residencies from the iorep) - cmd_data* cmd) // command line arg data (i.e. intervals) -{ - NSString* ptype_state = @"P"; - NSString* vtype_state = @"V"; - NSString* idletype_state = @"IDLE"; - NSString* offtype_state = @"OFF"; - - CFDictionaryRef cpusamp_a = IOReportCreateSamples(iorep->cpusub, iorep->cpusubchn, NULL); - CFDictionaryRef pwrsamp_a = IOReportCreateSamples(iorep->pwrsub, iorep->pwrsubchn, NULL); - CFDictionaryRef clpcsamp_a = IOReportCreateSamples(iorep->clpcsub, iorep->clpcsubchn, NULL); - - [NSThread sleepForTimeInterval: (cmd->interval * 1e-3)]; - - CFDictionaryRef cpusamp_b = IOReportCreateSamples(iorep->cpusub, iorep->cpusubchn, NULL); - CFDictionaryRef pwrsamp_b = IOReportCreateSamples(iorep->pwrsub, iorep->pwrsubchn, NULL); - CFDictionaryRef clpcsamp_b = IOReportCreateSamples(iorep->clpcsub, iorep->clpcsubchn, NULL); - - // deltas - CFDictionaryRef cpu_delta = IOReportCreateSamplesDelta(cpusamp_a, cpusamp_b, NULL); - CFDictionaryRef pwr_delta = IOReportCreateSamplesDelta(pwrsamp_a, pwrsamp_b, NULL); - CFDictionaryRef clpc_delta = IOReportCreateSamplesDelta(clpcsamp_a, clpcsamp_b, NULL); - - CFRelease(cpusamp_a); - CFRelease(cpusamp_b); - CFRelease(pwrsamp_a); - CFRelease(pwrsamp_b); - CFRelease(clpcsamp_a); - CFRelease(clpcsamp_b); - - IOReportIterate(cpu_delta, ^(IOReportSampleRef sample) { - for (int i = 0; i < IOReportStateGetCount(sample); i++) { - NSString* subgroup = IOReportChannelGetSubGroup(sample); - NSString* idx_name = IOReportStateGetNameForIndex(sample, i); - NSString* chann_name = IOReportChannelGetChannelName(sample); - uint64_t residency = IOReportStateGetResidency(sample, i); - - for (int ii = 0; ii < [sd->complex_freq_channels count]; ii++) { - if ([subgroup isEqual: @"CPU Complex Performance States"] || [subgroup isEqual: @"GPU Performance States"]) - { - if ([chann_name isEqual:sd->complex_freq_channels[ii]]) - { - if ([idx_name rangeOfString:ptype_state].location != NSNotFound || - [idx_name rangeOfString:vtype_state].location != NSNotFound) - { - NSNumber* a = [[NSNumber alloc] initWithUnsignedLongLong:([vd->cluster_sums[ii] unsignedLongLongValue] + residency)]; - NSNumber* b = [[NSNumber alloc] initWithUnsignedLongLong:residency]; - - vd->cluster_sums[ii] = a; - [vd->cluster_residencies[ii] addObject:b]; - - a = nil; - b = nil; - - } else if ([idx_name rangeOfString:idletype_state].location != NSNotFound || - [idx_name rangeOfString:offtype_state].location != NSNotFound) - { - NSNumber* a = [[NSNumber alloc] initWithUnsignedLongLong:residency]; - - vd->cluster_use[ii] = a; - - a = nil; - } - } - } - else if ([subgroup isEqual:@"CPU Core Performance States"]) - { - if (ii <= ([sd->cluster_core_counts count]-1)) - { - for (int iii = 0; iii < [sd->cluster_core_counts[ii] intValue]; iii++) - { - @autoreleasepool { - NSString* key = [NSString stringWithFormat:@"%@%d",sd->core_freq_channels[ii], iii, nil]; - - if ([chann_name isEqual:key]) { - if ([idx_name rangeOfString:ptype_state].location != NSNotFound || - [idx_name rangeOfString:vtype_state].location != NSNotFound) - { - NSNumber* a = [[NSNumber alloc] initWithUnsignedLongLong:([vd->core_sums[ii][iii] unsignedLongLongValue] + residency)]; - NSNumber* b = [[NSNumber alloc] initWithUnsignedLongLong:residency]; - - vd->core_sums[ii][iii] = a; - [vd->core_residencies[ii][iii] addObject:b]; - - a = nil; - b = nil; - - } else if ([idx_name rangeOfString:idletype_state].location != NSNotFound || - [idx_name rangeOfString:offtype_state].location != NSNotFound) - { - NSNumber* a = [[NSNumber alloc] initWithUnsignedLongLong:residency]; - - vd->core_use[ii][iii] = a; - - a = nil; - - } - } - - key = nil; - } - } - } - } - } - - chann_name = nil; - subgroup = nil; - idx_name = nil; - } - - return kIOReportIterOk; - }); - - IOReportIterate(pwr_delta, ^(IOReportSampleRef sample) { - NSString* chann_name = IOReportChannelGetChannelName(sample); - NSString* group = IOReportChannelGetGroup(sample); - long value = IOReportSimpleGetIntegerValue(sample, 0); - - if ([group isEqual:@"Energy Model"]) { - for (int ii = 0; ii < [sd->complex_freq_channels count]; ii++) { - - if ([chann_name isEqual:sd->complex_pwr_channels[ii]]) - { - NSNumber* a = [[NSNumber alloc] initWithFloat:(float)value/(cmd->interval*1e-3)]; - - vd->cluster_pwrs[ii] = a; - - a = nil; - } - - if (ii <= ([sd->cluster_core_counts count]-1)) - { - for (int iii = 0; iii < [sd->cluster_core_counts[ii] intValue]; iii++) - { - @autoreleasepool - { - NSString* val = [[NSString alloc] initWithFormat:@"%@%d",sd->core_pwr_channels[ii], iii, nil]; - - if ([chann_name isEqual:val]) - { - NSNumber* a = [[NSNumber alloc] initWithFloat:(float)value/(cmd->interval*1e-3)]; - - vd->core_pwrs[ii][iii] = a; - - a = nil; - } - - val = nil; - - } - } - } - } - } - - /* - * the GPU entry doen't seem to exist on Apple M1 Energy Model (probably same with M2) - * so we are grabbing that from the PMP - */ - if ([group isEqual:@"PMP"] && [chann_name isEqual:@"GPU"]) { - if ([sd->extra[0] isEqual:@"Apple M1"] || [sd->extra[0] isEqual:@"Apple M2"]) { - - NSNumber* a = [[NSNumber alloc] initWithFloat:(float)value/(cmd->interval*1e-3)]; - - vd->cluster_pwrs[[vd->cluster_pwrs count]-1] = a; - - a = nil; - } - } - - chann_name = nil; - group = nil; - - return kIOReportIterOk; - }); - - IOReportIterate(clpc_delta, ^(IOReportSampleRef sample) { - NSString* chann_name = IOReportChannelGetChannelName(sample); - - for (int i = 0; i < [sd->cluster_core_counts count]; i++) { - long value = IOReportArrayGetValueAtIndex(sample, i); - - NSNumber* a = [[NSNumber alloc] initWithLong:value]; - - if ([chann_name isEqual:@"CPU cycles, by cluster"]) - [vd->cluster_instrcts_clk addObject:a]; - if ([chann_name isEqual:@"CPU instructions, by cluster"]) - [vd->cluster_instrcts_ret addObject:a]; - - a = nil; - } - - if ([vd->cluster_instrcts_ret count] == [sd->cluster_core_counts count]) return kIOReportIterFailed; // Naming makes this an incorrect usage but it exits our iteration, so... - - chann_name = nil; - - return kIOReportIterOk; - }); - - CFRelease(cpu_delta); - CFRelease(pwr_delta); - CFRelease(clpc_delta); -} - -void format(static_data* sd, variating_data* vd) -{ - uint64_t res = 0; - uint64_t core_res = 0; - - for (int i = 0; i < [sd->complex_freq_channels count]; i++) { - /* formatting cpu freqs */ - for (int ii = 0; ii < [vd->cluster_residencies[i] count]; ii++) - { - @autoreleasepool - { - res = [vd->cluster_residencies[i][ii] unsignedLongLongValue]; - - if (res != 0) - { - float perc = (res / [vd->cluster_sums[i] floatValue]);\ - - NSNumber* a = [[NSNumber alloc] initWithFloat: perc]; - NSNumber* b = [[NSNumber alloc] initWithFloat: ([vd->cluster_freqs[i] floatValue] + ([sd->dvfm_states[i][ii] floatValue]*perc))]; - NSNumber* v = [[NSNumber alloc] initWithFloat: ([vd->cluster_volts[i] floatValue] + ([sd->dvfm_states_voltages[i][ii] floatValue]*perc))]; - - vd->cluster_freqs[i] = b; - vd->cluster_volts[i] = v; - [vd->cluster_residencies[i] replaceObjectAtIndex:ii withObject:a]; - - a = nil; - b = nil; - v = nil; - } - - if (i <= ([sd->cluster_core_counts count]-1)) { - for (int iii = 0; iii < [sd->cluster_core_counts[i] intValue]; iii++) { - - core_res = [vd->core_residencies[i][iii][ii] unsignedLongLongValue]; - - if (core_res != 0) - { - float core_perc = (core_res / [vd->core_sums[i][iii] floatValue]); - - NSNumber* a = [[NSNumber alloc] initWithFloat:core_perc]; - NSNumber* b = [[NSNumber alloc] initWithFloat: ([vd->core_freqs[i][iii] floatValue] + - ([sd->dvfm_states[i][ii] floatValue] * - core_perc))]; - NSNumber* v = [[NSNumber alloc] initWithFloat: ([vd->core_volts[i][iii] floatValue] + - ([sd->dvfm_states_voltages[i][ii] floatValue] * - core_perc))]; - - vd->core_freqs[i][iii] = b; - vd->core_volts[i][iii] = v; - [vd->core_residencies[i][iii] replaceObjectAtIndex:ii withObject:a]; - - a = nil; - b = nil; - v = nil; - } - } - } - } - } - - /* formatting idle residency */ - vd->cluster_use[i] = [[NSNumber alloc] initWithFloat:(([vd->cluster_use[i] floatValue] / - ([vd->cluster_sums[i] floatValue] + - [vd->cluster_use[i] floatValue])) * 100)]; - - if (i <= ([sd->cluster_core_counts count]-1)) { - for (int iii = 0; iii < [sd->cluster_core_counts[i] intValue]; iii++) { - NSNumber* a = [[NSNumber alloc] initWithFloat:(100 - ([vd->core_use[i][iii] floatValue] / - ([vd->core_sums[i][iii] floatValue] + - [vd->core_use[i][iii] floatValue])) * 100)]; - vd->core_use[i][iii] = a; - - a = nil; - } - } - } -} diff --git a/SocPowerBuddy/socpwrbud.h b/SocPowerBuddy/socpwrbud.h deleted file mode 100644 index 947bed0..0000000 --- a/SocPowerBuddy/socpwrbud.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * samplers.h - * SocPowerBuddy - * - * Created by BitesPotatoBacks on 7/19/22. - * Copyright (c) 2022 BitesPotatoBacks. - */ - -#ifndef socpwrbud_h -#define socpwrbud_h - -#include -#include - -/* - * Extern declarations - */ -enum { - kIOReportIterOk, - kIOReportIterFailed, - kIOReportIterSkipped -}; - -typedef struct IOReportSubscriptionRef* IOReportSubscriptionRef; -typedef CFDictionaryRef IOReportSampleRef; - -extern IOReportSubscriptionRef IOReportCreateSubscription(void* a, CFMutableDictionaryRef desiredChannels, CFMutableDictionaryRef* subbedChannels, uint64_t channel_id, CFTypeRef b); -extern CFDictionaryRef IOReportCreateSamples(IOReportSubscriptionRef iorsub, CFMutableDictionaryRef subbedChannels, CFTypeRef a); -extern CFDictionaryRef IOReportCreateSamplesDelta(CFDictionaryRef prev, CFDictionaryRef current, CFTypeRef a); - -extern CFMutableDictionaryRef IOReportCopyChannelsInGroup(NSString*, NSString*, uint64_t, uint64_t, uint64_t); - -typedef int (^ioreportiterateblock)(IOReportSampleRef ch); -extern void IOReportIterate(CFDictionaryRef samples, ioreportiterateblock); - -extern int IOReportStateGetCount(CFDictionaryRef); -extern uint64_t IOReportStateGetResidency(CFDictionaryRef, int); -extern uint64_t IOReportArrayGetValueAtIndex(CFDictionaryRef, int); -extern long IOReportSimpleGetIntegerValue(CFDictionaryRef, int); -extern NSString* IOReportChannelGetChannelName(CFDictionaryRef); -extern NSString* IOReportChannelGetSubGroup(CFDictionaryRef); -extern NSString* IOReportStateGetNameForIndex(CFDictionaryRef, int); - -extern void IOReportMergeChannels(CFMutableDictionaryRef, CFMutableDictionaryRef, CFTypeRef); -extern NSString* IOReportChannelGetGroup(CFDictionaryRef); -/* - * Typedefs - */ - -/* raw data form the ioreport */ -typedef struct { - /* data for Energy Model*/ - IOReportSubscriptionRef pwrsub; - CFMutableDictionaryRef pwrsubchn; - CFMutableDictionaryRef pwrchn_eng; - CFMutableDictionaryRef pwrchn_pmp; - - /* datat for CPU/GPU Stats */ - IOReportSubscriptionRef cpusub; - CFMutableDictionaryRef cpusubchn; - CFMutableDictionaryRef cpuchn_cpu; - CFMutableDictionaryRef cpuchn_gpu; - - /* data for CLPC Stats*/ - IOReportSubscriptionRef clpcsub; - CFMutableDictionaryRef clpcsubchn; - CFMutableDictionaryRef clpcchn; -} iorep_data; - -typedef struct { - NSArray* complex_pwr_channels; - NSArray* core_pwr_channels; - - NSArray* complex_freq_channels; - NSArray* core_freq_channels; - - NSMutableArray* dvfm_states_holder; - NSArray* dvfm_states; - - NSMutableArray* dvfm_states_voltages_holder; - NSArray* dvfm_states_voltages; - - NSMutableArray* cluster_core_counts; - int gpu_core_count; - - NSMutableArray* extra; -} static_data; - -typedef struct { - /* data for freqs, dvfm, and res */ - NSMutableArray* cluster_sums; - NSMutableArray* cluster_residencies; - NSMutableArray* cluster_freqs; - NSMutableArray* cluster_use; - - NSMutableArray* core_sums; - NSMutableArray* core_residencies; - NSMutableArray* core_freqs; - NSMutableArray* core_use; - - /* data for power draw */ - NSMutableArray* cluster_pwrs; - NSMutableArray* core_pwrs; - - /* data for (milli)voltage */ - NSMutableArray* cluster_volts; - NSMutableArray* core_volts; - - /* data for instructions and cycles */ - NSMutableArray* cluster_instrcts_ret; - NSMutableArray* cluster_instrcts_clk; -// -// unsigned long package_instrcts_ret; -// unsigned long package_instrcts_clk; -} variating_data; - -/* for cmd opts */ -typedef struct cmd_data { - float power_measure; - float freq_measure; - const char* power_measure_un; - const char* freq_measure_un; - - unsigned int interval; - int samples; - NSArray* metrics; - NSArray* hide_units; - - bool plist; - FILE * file_out; -} cmd_data; - -/* for units/metrics args */ -typedef struct { - /* units */ - bool ecpu; - bool pcpu; - bool gpu; -// bool ane; - /* metrics */ - bool res; - bool idle; - bool freq; - bool cores; - bool dvfm; - bool dvfm_ms; - bool dvfm_volts; - bool power; - bool volts; - bool intstrcts; - bool cycles; -} bool_data; - - -/* - * Function declarations - */ -void error(int, const char*, ...); -void textOutput(iorep_data*, static_data*, variating_data*, bool_data*, cmd_data*, unsigned int); -void plistOutput(iorep_data*, static_data*, variating_data*, bool_data*, cmd_data*, unsigned int); - -void sample(iorep_data*, static_data*, variating_data*, cmd_data*); -void format(static_data*, variating_data*); - -void generateDvfmTable(static_data*); -void generateCoreCounts(static_data*); -void generateProcessorName(static_data*); -void generateSiliconCodename(static_data*); -void generateMicroArchs(static_data*); - -#endif /* socpwrbud_h */ diff --git a/SocPowerBuddy/socpwrbud.m b/SocPowerBuddy/socpwrbud.m deleted file mode 100644 index 491e682..0000000 --- a/SocPowerBuddy/socpwrbud.m +++ /dev/null @@ -1,539 +0,0 @@ -/* - * socpwrbud.m - * SocPowerBuddy - * - * Created by BitesPotatoBacks on 6/30/22. - * Copyright (c) 2022 BitesPotatoBacks. - */ - -#include -#include -#include "socpwrbud.h" - -/* - * Main Macros - */ -#define __RELEASE__ "v0.4" - -#define METRIC_ACTIVE "%active" -#define METRIC_IDLE "%idle" -#define METRIC_FREQ "freq" -#define METRIC_DVFM "dvfm" -#define METRIC_DVFMMS "dvfm_ms" -#define METRIC_DVFMVOLTS "dvfm_volts" -#define METRIC_POWER "power" -#define METRIC_VOLTS "volts" -#define METRIC_INSTRCTS "intstrcts" -#define METRIC_CYCLES "cycles" -#define METRIC_CORES "cores" - -#define UNIT_ECPU "ecpu" -#define UNIT_PCPU "pcpu" -#define UNIT_GPU "gpu" -//#define UNIT_ANE "ane" - -/* - * Typedefs - */ -typedef struct param_set { - const char* param_name; - const char* description; -} param_set; - -typedef struct long_opts_extended { - struct option getopt_long; - const char* description; -} long_opts_extended; - -/* - * Global misc - */ -#define METRIC_COUNT 11 - -static struct param_set metrics_set[] = -{ - { METRIC_ACTIVE, "show active residencies" }, - { METRIC_IDLE, "show idle residencies" }, - { METRIC_FREQ, "show active frequencies" }, - { METRIC_DVFM, "show dvfm state distributions" }, - { METRIC_DVFMVOLTS, "show (milli)volts of dvfm states" }, - { METRIC_DVFMMS, "show time spent in ms of dvfm states" }, - { METRIC_POWER, "show power consumption of units" }, - { METRIC_VOLTS, "show voltage of units" }, - { METRIC_INSTRCTS, "show instructions retired / per-clock metrics of supporting units" }, - { METRIC_CYCLES, "show the supposed cycles spent during sample of supporting units" }, - { METRIC_CORES, "show per-core stats for selected metrics on supporting units" } -}; - -#define UNITS_COUNT 3 - -static struct param_set units_set[] = -{ - { UNIT_ECPU, "efficiency cluster(s) statistics" }, - { UNIT_PCPU, "performance cluster(s) statistics" }, - { UNIT_GPU, "integrated graphics statistics" }, -// { UNIT_ANE, "neural engine statistics" }, -}; - -#define OPT_COUNT 11 - -static struct long_opts_extended long_opts_set[] = -{ - {{ "help", no_argument, 0, 'h' }, - " print this message and exit\n" - }, - {{ "version", no_argument, 0, 'v' }, - " print tool version number and exit\n\n" - }, - {{ "interval", required_argument, 0, 'i' }, - " perform samples between N ms [default: 175ms]\n" - }, - {{ "samples", required_argument, 0, 's' }, - " collect and display N samples (0=inf) [default: 1]\n" - }, - - {{ "output", required_argument, 0, 'o' }, - " set a file for metric stdout\n\n" - }, - {{ "hide-unit", required_argument, 0, 'H' }, - " comma separated list of unit statistics to hide\n" - }, - {{ "metrics", required_argument, 0, 'm' }, - " comma separated list of metrics to report\n" - }, - {{ "all-metrics", no_argument, 0, 'a' }, - " report all available metrics for the visible units\n\n" - }, - {{ "set-watts", no_argument, 0, 'w' }, - " set power measurement to watts (default is mW)\n" - }, - {{ "set-ghz", no_argument, 0, 'g' }, - " set frequency measurement to GHz (default is MHz)\n" - }, - {{ "property-list", no_argument, 0, 'p' }, - " output as property list rather than plain text\n\n" - }, -}; - -static void usage(cmd_data*); -static struct option* unextended_long_opts_extended(void); - -/* - * Main - */ -int main(int argc, char * argv[]) -{ - @autoreleasepool - { - iorep_data iorep; - variating_data vd; - static_data sd; - bool_data bd; - cmd_data cmd; - - int opt = 0; - int optindex = 0; - unsigned int current_loop = 0; - - cmd.power_measure = 1; - cmd.freq_measure = 1; - cmd.power_measure_un = "mW"; - cmd.freq_measure_un = "MHz"; - cmd.plist = false; - cmd.file_out = stdout; - - cmd.interval = 275; - cmd.samples = 1; - cmd.hide_units = [NSArray array]; - cmd.metrics = [NSArray arrayWithObjects:[NSString stringWithUTF8String: METRIC_ACTIVE], - [NSString stringWithUTF8String: METRIC_POWER], - [NSString stringWithUTF8String: METRIC_FREQ], - [NSString stringWithUTF8String: METRIC_DVFM], - [NSString stringWithUTF8String: METRIC_INSTRCTS], - [NSString stringWithUTF8String: METRIC_CORES], nil]; - bd.ecpu = true; - bd.pcpu = true; - bd.gpu = true; -// bd.ane = true; - - bd.res = false; - bd.idle = false; - bd.freq = false; - bd.cores = false; - bd.dvfm = false; - bd.dvfm_ms = false; - bd.power = false; - bd.volts = true; - bd.dvfm_volts = false; - bd.intstrcts = false; - bd.cycles = false; - - NSString* metrics_str; - NSString* hide_unit_str; - - struct option* long_opts = unextended_long_opts_extended(); - - while((opt = getopt_long(argc, argv, "hvi:s:po:m:H:wga", long_opts, &optindex)) != -1) { - switch(opt) { - case '?': - case 'h': usage(&cmd); - case 'v': printf("%s %s (build %s %s)\n", getprogname(), __RELEASE__, __DATE__, __TIME__); - return 0; - case 'i': cmd.interval = atoi(optarg); - break; - case 's': cmd.samples = atoi(optarg); - break; - case 'm': metrics_str = [NSString stringWithFormat:@"%s", strdup(optarg)]; - cmd.metrics = [metrics_str componentsSeparatedByString:@","]; - break; - case 'H': hide_unit_str = [NSString stringWithFormat:@"%s", strdup(optarg)]; - cmd.hide_units = [hide_unit_str componentsSeparatedByString:@","]; - break; - case 'w': cmd.power_measure = 1e-3; - cmd.power_measure_un = "W"; - break; - case 'g': cmd.freq_measure = 1e-3; - cmd.freq_measure_un = "GHz"; - break; - case 'p': cmd.plist = true; - break; - case 'o': cmd.file_out = fopen(strdup(optarg), "w"); - break; - case 'a': cmd.metrics = [NSArray arrayWithObjects:[NSString stringWithUTF8String: METRIC_ACTIVE], - [NSString stringWithUTF8String: METRIC_IDLE], - [NSString stringWithUTF8String: METRIC_DVFM], - [NSString stringWithUTF8String: METRIC_DVFMMS], - [NSString stringWithUTF8String: METRIC_DVFMVOLTS], - [NSString stringWithUTF8String: METRIC_VOLTS], - [NSString stringWithUTF8String: METRIC_POWER], - [NSString stringWithUTF8String: METRIC_INSTRCTS], - [NSString stringWithUTF8String: METRIC_FREQ], - [NSString stringWithUTF8String: METRIC_CYCLES], - [NSString stringWithUTF8String: METRIC_CORES], nil]; - } - } - - for (int i = 0; i < [cmd.metrics count]; i++) { - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_ACTIVE]]) { - bd.res = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_IDLE]]) { - bd.idle = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_FREQ]]) { - bd.freq = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_CORES]]) { - bd.cores = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_DVFM]]) { - bd.dvfm = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_DVFMMS]]) { - bd.dvfm = true; - bd.dvfm_ms = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_DVFMVOLTS]]) { - bd.dvfm = true; - bd.dvfm_volts = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_POWER]]) { - bd.power = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_VOLTS]]) { - bd.volts = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_INSTRCTS]]) { - bd.intstrcts = true; - continue; - } - if ([cmd.metrics[i] isEqual:[NSString stringWithUTF8String:METRIC_CYCLES]]) { - bd.cycles = true; - continue; - } - - error(1, "Incorrect metric option \"%s\" in list", [cmd.metrics[i] UTF8String]); - } - - for (int i = 0; i < [cmd.hide_units count]; i++) { - if ([cmd.hide_units[i] isEqual:[NSString stringWithUTF8String:UNIT_ECPU]]) bd.ecpu = false; - else if ([cmd.hide_units[i] isEqual:[NSString stringWithUTF8String:UNIT_PCPU]]) bd.pcpu = false; - else if ([cmd.hide_units[i] isEqual:[NSString stringWithUTF8String:UNIT_GPU]]) bd.gpu = false; -// else if ([cmd.hide_units[i] isEqual:[NSString stringWithUTF8String:UNIT_ANE]]) bd.ane = false; - else error(1, "Incorrect unit option \"%s\" in list", [cmd.hide_units[i] UTF8String]); - } - - if (cmd.interval < 1) cmd.interval = 1; - - /* - * init our data - */ - sd.gpu_core_count = 0; - sd.dvfm_states_holder = [[NSMutableArray alloc] init]; - sd.dvfm_states_voltages_holder = [[NSMutableArray alloc] init]; - sd.cluster_core_counts = [[NSMutableArray alloc] init]; - sd.extra = [[NSMutableArray alloc] init]; - - vd.cluster_sums = [[NSMutableArray alloc] init]; - vd.cluster_residencies = [[NSMutableArray alloc] init]; - vd.cluster_freqs = [[NSMutableArray alloc] init]; - vd.cluster_use = [[NSMutableArray alloc] init]; - - vd.core_sums = [[NSMutableArray alloc] init]; - vd.core_residencies = [[NSMutableArray alloc] init]; - vd.core_freqs = [[NSMutableArray alloc] init]; - vd.core_use = [[NSMutableArray alloc] init]; - - vd.cluster_pwrs = [[NSMutableArray alloc] init]; - vd.core_pwrs = [[NSMutableArray alloc] init]; - - vd.cluster_volts = [[NSMutableArray alloc] init]; - vd.core_volts = [[NSMutableArray alloc] init]; - - vd.cluster_instrcts_ret = [[NSMutableArray alloc] init]; - vd.cluster_instrcts_clk = [[NSMutableArray alloc] init]; - - generateProcessorName(&sd); - - generateDvfmTable(&sd); - generateCoreCounts(&sd); - generateSiliconCodename(&sd); - generateMicroArchs(&sd); - - /* - * generating data to support other silicon - */ - - NSString* name = [sd.extra[0] lowercaseString]; - - if ([name rangeOfString:@"virtual"].location != NSNotFound) { - error(1, "Running this tool in a Virtual Machine is not allowed"); - } - - if (([sd.extra[0] rangeOfString:@"pro"].location != NSNotFound) || - ([sd.extra[0] rangeOfString:@"max"].location != NSNotFound)) - { - sd.complex_pwr_channels = @[@"EACC_CPU", @"PACC0_CPU", @"PACC1_CPU", @"GPU0"]; - sd.core_pwr_channels = @[@"EACC_CPU", @"PACC0_CPU", @"PACC1_CPU"]; - - sd.complex_freq_channels = @[@"ECPU", @"PCPU", @"PCPU1", @"GPUPH"]; - sd.core_freq_channels = @[@"ECPU0", @"PCPU0", @"PCPU1"]; - - sd.dvfm_states = @[sd.dvfm_states_holder[0], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[2]]; - - sd.dvfm_states_voltages = @[sd.dvfm_states_voltages_holder[0], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[2]]; - - } else if ([sd.extra[0] rangeOfString:@"ultra"].location != NSNotFound) { - sd.complex_pwr_channels = @[@"DIE_0_EACC_CPU", @"DIE_1_EACC_CPU", @"DIE_0_PACC0_CPU", @"DIE_0_PACC1_CPU", @"DIE_1_PACC0_CPU", @"DIE_1_PACC1_CPU", @"GPU0_0"]; - sd.core_pwr_channels = @[@"DIE_0_EACC_CPU", @"DIE_1_EACC_CPU", @"DIE_0_PACC0_CPU", @"DIE_0_PACC1_CPU", @"DIE_1_PACC0_CPU", @"DIE_1_PACC1_CPU"]; - - sd.complex_freq_channels = @[@"DIE_0_ECPU", @"DIE_1_ECPU", @"DIE_0_PCPU", @"DIE_0_PCPU1", @"DIE_1_PCPU", @"DIE_1_PCPU1", @"GPUPH"]; - sd.core_freq_channels = @[@"DIE_0_ECPU_CPU", @"DIE_1_ECPU_CPU", @"DIE_0_PCPU_CPU", @"DIE_0_PCPU1_CPU", @"DIE_1_PCPU_CPU", @"DIE_1_PCPU1_CPU"]; - - sd.dvfm_states = @[sd.dvfm_states_holder[0], - sd.dvfm_states_holder[0], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[2]]; - - sd.dvfm_states_voltages = @[sd.dvfm_states_voltages_holder[0], - sd.dvfm_states_voltages_holder[0], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[2]]; - } else { - sd.complex_pwr_channels = @[@"ECPU", @"PCPU", @"GPU"]; - sd.core_pwr_channels = @[@"ECPU", @"PCPU"]; - - sd.complex_freq_channels = @[@"ECPU", @"PCPU", @"GPUPH"]; - sd.core_freq_channels = @[@"ECPU", @"PCPU"]; - - sd.dvfm_states = @[sd.dvfm_states_holder[0], - sd.dvfm_states_holder[1], - sd.dvfm_states_holder[2]]; - - sd.dvfm_states_voltages = @[sd.dvfm_states_voltages_holder[0], - sd.dvfm_states_voltages_holder[1], - sd.dvfm_states_voltages_holder[2]]; - } - - /* - * adding the proper object counts to our arrays based on cores/complexes - */ - for (int i = 0; i < ([sd.cluster_core_counts count]+1); i++) { - [vd.cluster_residencies addObject:[NSMutableArray array]]; - [vd.cluster_pwrs addObject:@0]; - [vd.cluster_volts addObject:@0]; - [vd.cluster_freqs addObject:@0]; - [vd.cluster_use addObject:@0]; - [vd.cluster_sums addObject:@0]; - - if (i <= ([sd.cluster_core_counts count]-1)) { - [vd.core_pwrs addObject:[NSMutableArray array]]; - [vd.core_volts addObject:[NSMutableArray array]]; - [vd.core_residencies addObject:[NSMutableArray array]]; - [vd.core_freqs addObject:[NSMutableArray array]]; - [vd.core_use addObject:[NSMutableArray array]]; - [vd.core_sums addObject:[NSMutableArray array]]; - } - } - - for (int i = 0; i < ([sd.cluster_core_counts count]); i++) { - for (int ii = 0; ii < [sd.cluster_core_counts[i] intValue]; ii++) { - [vd.core_pwrs[i] addObject:[NSMutableArray array]]; - [vd.core_residencies[i] addObject:[NSMutableArray array]]; - [vd.core_use[i] addObject:@0]; - [vd.core_freqs[i] addObject:@0]; - [vd.core_volts[i] addObject:@0]; - [vd.core_sums[i] addObject:@0]; - } - } - - /* - * subscribing to ioreport - * doing it outside of sampling function, that way we don't waste resources constantly subscribing when looping - */ - iorep.cpusubchn = NULL; - iorep.pwrsubchn = NULL; - iorep.clpcsubchn = NULL; - iorep.cpuchn_cpu = IOReportCopyChannelsInGroup(@"CPU Stats", 0, 0, 0, 0); - iorep.cpuchn_gpu = IOReportCopyChannelsInGroup(@"GPU Stats", 0, 0, 0, 0); - iorep.pwrchn_eng = IOReportCopyChannelsInGroup(@"Energy Model", 0, 0, 0, 0); - iorep.pwrchn_pmp = IOReportCopyChannelsInGroup(@"PMP", 0, 0, 0, 0); - iorep.clpcchn = IOReportCopyChannelsInGroup(@"CLPC Stats", 0, 0, 0, 0); - - IOReportMergeChannels(iorep.cpuchn_cpu, iorep.cpuchn_gpu, NULL); - IOReportMergeChannels(iorep.pwrchn_eng, iorep.pwrchn_pmp, NULL); - - iorep.cpusub = IOReportCreateSubscription(NULL, iorep.cpuchn_cpu, &iorep.cpusubchn, 0, 0); - iorep.pwrsub = IOReportCreateSubscription(NULL, iorep.pwrchn_eng, &iorep.pwrsubchn, 0, 0); - iorep.clpcsub = IOReportCreateSubscription(NULL, iorep.clpcchn, &iorep.clpcsubchn, 0, 0); - - CFRelease(iorep.cpuchn_cpu); - CFRelease(iorep.cpuchn_gpu); - CFRelease(iorep.pwrchn_eng); - CFRelease(iorep.pwrchn_pmp); - CFRelease(iorep.clpcchn); - - /* - * dealing with outputing - */ - if (cmd.samples <= 0) cmd.samples = -1; - for(int L = cmd.samples; L--;) { - sample(&iorep, &sd, &vd, &cmd); - format(&sd, &vd); - - if (cmd.plist == false) - textOutput(&iorep, &sd, &vd, &bd, &cmd, current_loop); - else { - fprintf(cmd.file_out, "\n"); - fprintf(cmd.file_out, "\n"); - fprintf(cmd.file_out, "\n"); - - fprintf(cmd.file_out, "\n"); - plistOutput(&iorep, &sd, &vd, &bd, &cmd, current_loop); - fprintf(cmd.file_out, "\n\n"); - } - - /* - * emptying our arrays for the next loop - */ - for (int i = 0; i < ([sd.cluster_core_counts count]+1); i++) { - [vd.cluster_residencies[i] removeAllObjects]; - vd.cluster_pwrs[i] = @0; - vd.cluster_volts[i] = @0; - vd.cluster_use[i] = @0; - vd.cluster_sums[i] = @0; - vd.cluster_freqs[i] = @0; - } - - for (int i = 0; i < ([sd.cluster_core_counts count]); i++) { - for (int ii = 0; ii < [sd.cluster_core_counts[i] intValue]; ii++) { - [vd.core_residencies[i][ii] removeAllObjects]; - vd.core_pwrs[i][ii] = @0; - vd.core_volts[i][ii] = @0; - vd.core_use[i][ii] = @0; - vd.core_freqs[i][ii] = @0; - vd.core_sums[i][ii] = @0; - } - } - - current_loop++; - } - } - - return 0; -} - -/* - * Usage - */ -static void usage(cmd_data*cmd) -{ - fprintf(cmd->file_out, "\e[1m\nUsage: %s [-wgap] [-i interval] [-s samples]\n\n\e[0m", getprogname()); - fprintf(cmd->file_out, " A sudoless tool to profile your Apple M-Series CPU+GPU active core\n and cluster frequencies, residencies, power consumption, and other metrics.\n Inspired by Powermetrics. Made with love by BitesPotatoBacks.\n\n\e[1mThe following command-line options are supported:\e[0m\n\n"); - - for (int i = 0; i < OPT_COUNT; i++) - fprintf(cmd->file_out, " -%c, --%s%s", long_opts_set[i].getopt_long.val, long_opts_set[i].getopt_long.name, long_opts_set[i].description); - - fprintf(cmd->file_out, "\e[1mThe following are metrics supported by --metrics:\e[0m\n\n"); - - for (int i = 0; i < METRIC_COUNT; i++) - fprintf(cmd->file_out, " %-15s%s\n", metrics_set[i].param_name, metrics_set[i].description); - - fprintf(cmd->file_out, "\n default: %s,%s,%s,%s,%s\n\n\e[1mThe following are units supported by --hide-units:\e[0m\n\n", METRIC_ACTIVE, METRIC_FREQ, METRIC_DVFM, METRIC_INSTRCTS, METRIC_CORES); - - for (int i = 0; i < UNITS_COUNT; i++) - fprintf(cmd->file_out, " %-15s%s\n", units_set[i].param_name, units_set[i].description); - - exit(0); -} - - -/* - * we're using a customized struct for our long opts that way we can store definitions for them - * this function is to convert that struct back the flavor we need for getopt_long() - * inspired by a method found in pmtool - */ -static struct option* unextended_long_opts_extended(void) -{ - int count = sizeof(long_opts_set) / sizeof(long_opts_extended); - struct option* retopt = calloc(count, sizeof(struct option)); - - for (int i = 0; i < count; i++) - bcopy(&long_opts_set[i].getopt_long, &retopt[i], sizeof(struct option)); - - return retopt; -} - -/* - * nice error formatting with exitting - */ -void error(int exitcode, const char* format, ...) { - va_list args; - fprintf(stderr, "\e[1m%s:\033[0;31m error:\033[0m\e[0m ", getprogname()); - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - exit(exitcode); -} diff --git a/SocPowerBuddy/static.m b/SocPowerBuddy/static.m deleted file mode 100644 index ff5e380..0000000 --- a/SocPowerBuddy/static.m +++ /dev/null @@ -1,280 +0,0 @@ -/* - * static.m - * SocPowerBuddy - * - * Created by BitesPotatoBacks on 7/19/22. - * Copyright (c) 2022 BitesPotatoBacks. - */ - -#include "socpwrbud.h" - -/* - * gather our dvfm nominal freq arrays - */ -void generateDvfmTable(static_data* sd) -{ - NSData* frmt_data; - - const unsigned char* databytes; - - io_registry_entry_t entry; - io_iterator_t iter; - mach_port_t port = kIOMasterPortDefault; - - CFMutableDictionaryRef service; - - if (@available(macOS 12, *)) port = kIOMainPortDefault; - - /* accessing pmgr for dvfm freqs, using a service matching method to increase portability */ - if (!(service = IOServiceMatching("AppleARMIODevice"))) - error(1, "Failed to find AppleARMIODevice service in IORegistry"); - if (!(IOServiceGetMatchingServices(port, service, &iter) == kIOReturnSuccess)) - error(1, "Failed to access AppleARMIODevice service in IORegistry"); - - while ((entry = IOIteratorNext(iter)) != IO_OBJECT_NULL) { - if (IORegistryEntryCreateCFProperty(entry, CFSTR("voltage-states1-sram"), kCFAllocatorDefault, 0) != nil) { - - for (int i = 3; i--;) { - const void* data = nil; - - /* maybe i'll add voltage-states-13-sram in the future for higher end silicon, but it's not all that necessary anyway... */ - switch(i) { - case 2: data = IORegistryEntryCreateCFProperty(entry, CFSTR("voltage-states1-sram"), kCFAllocatorDefault, 0); break; - case 1: data = IORegistryEntryCreateCFProperty(entry, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, 0); break; - case 0: data = IORegistryEntryCreateCFProperty(entry, CFSTR("voltage-states9"), kCFAllocatorDefault, 0); break; - } - - if (data != nil) { - [sd->dvfm_states_holder addObject:[NSMutableArray array]]; - [sd->dvfm_states_voltages_holder addObject:[NSMutableArray array]]; - - frmt_data = (NSData*)CFBridgingRelease(data); - databytes = [frmt_data bytes]; - - /* data is formatted as 32-bit litte-endian hexadecimal, converting to an array of human readable integers */ - for (int ii = 4; ii < ([frmt_data length] + 4); ii += 8) { - NSString* datastrng = [[NSString alloc] initWithFormat:@"0x%02x%02x%02x%02x", databytes[ii-1], databytes[ii-2], databytes[ii-3], databytes[ii-4]]; - - float freq = atof([datastrng UTF8String]) * 1e-6; - - if (freq != 0) [sd->dvfm_states_holder[2-i] addObject:[NSNumber numberWithFloat:freq]]; - - datastrng = nil; - } - - for (int ii = 4; ii < ([frmt_data length]); ii += 8) { - NSString* datastrng = [[NSString alloc] initWithFormat:@"0x%02x%02x%02x%02x", databytes[ii+3], databytes[ii+2], databytes[ii+1], databytes[ii]]; - - float volts = atof([datastrng UTF8String]); - - if (volts != 0) [sd->dvfm_states_voltages_holder[2-i] addObject:[NSNumber numberWithFloat:volts]]; - - datastrng = nil; - } - } - } - - break; - } - } - - IOObjectRelease(entry); - IOObjectRelease(iter); -} - -/* - * gather our complex core counts - */ -void generateCoreCounts(static_data* sd) -{ - io_registry_entry_t entry; - io_iterator_t iter; - mach_port_t port = kIOMasterPortDefault; - - CFMutableDictionaryRef service; - - if (@available(macOS 12, *)) port = kIOMainPortDefault; - - /* reading cluster core counts from the pmgr again with a service matching method */ - if (!(service = IOServiceMatching("AppleARMIODevice"))) - error(1, "Failed to find AppleARMIODevice service in IORegistry"); - if (!(IOServiceGetMatchingServices(port, service, &iter) == kIOReturnSuccess)) - error(1, "Failed to access AppleARMIODevice service in IORegistry"); - - while ((entry = IOIteratorNext(iter)) != IO_OBJECT_NULL) { - const void* data = IORegistryEntryCreateCFProperty(entry, CFSTR("clusters"), kCFAllocatorDefault, 0); - - if (data != nil) { - NSData* frmt_data = (NSData*)CFBridgingRelease(data); - const unsigned char* databytes = [frmt_data bytes]; - - /* every 4th index after the first is our byte data for the cluster core count */ - for (int ii = 0; ii < [frmt_data length]; ii += 4) { - NSString* datastrng = [[NSString alloc] initWithFormat:@"%02x", databytes[ii]]; - - /* Ultra support */ - if ([sd->extra[0] rangeOfString:@"Ultra"].location != NSNotFound) { - for (int i = 2; i--;) - [sd->cluster_core_counts addObject:[NSNumber numberWithInt: (int) atof([datastrng UTF8String])]]; - } else - [sd->cluster_core_counts addObject:[NSNumber numberWithInt: (int) atof([datastrng UTF8String])]]; - - datastrng = nil; - } - - break; - } - } - - /* pull gpu core counts from a different spot */ - if (!(service = IOServiceMatching("AGXAccelerator"))) - error(1, "Failed to find AGXAccelerator service in IORegistry"); - if (!(IOServiceGetMatchingServices(port, service, &iter) == kIOReturnSuccess)) - error(1, "Failed to access AGXAccelerator service in IORegistry"); - - while ((entry = IOIteratorNext(iter)) != IO_OBJECT_NULL) { - - CFTypeRef a = IORegistryEntryCreateCFProperty(entry, CFSTR("gpu-core-count"), kCFAllocatorDefault, 0); - if (a != nil) - sd->gpu_core_count = [(__bridge NSNumber *)a intValue]; - - break; - } - - IOObjectRelease(entry); - IOObjectRelease(iter); -} - -/* - * find silicon id from ioreg - */ -void generateSiliconCodename(static_data * sd) -{ - io_registry_entry_t entry; - io_iterator_t iter; - mach_port_t port = kIOMasterPortDefault; - - CFMutableDictionaryRef servicedict; - CFMutableDictionaryRef service; - - if (!(service = IOServiceMatching("IOPlatformExpertDevice"))) - goto error; - if (!(IOServiceGetMatchingServices(port, service, &iter) == kIOReturnSuccess)) - goto error; - - while ((entry = IOIteratorNext(iter)) != IO_OBJECT_NULL) { - if ((IORegistryEntryCreateCFProperties(entry, &servicedict, kCFAllocatorDefault, 0) != kIOReturnSuccess)) - goto error; - - const void* data = CFDictionaryGetValue(servicedict, @"platform-name");; - - if (data != nil) { - NSData* frmt_data = (NSData*)CFBridgingRelease(data); - - const unsigned char* databytes = [frmt_data bytes]; - - [sd->extra addObject:[[NSString stringWithFormat:@"%s", databytes] capitalizedString]]; - - frmt_data = nil; - } else - goto error; - } - - IOObjectRelease(entry); - IOObjectRelease(iter); -// CFRelease(service); - - return; - -error: - /* find the silicon codename using stored strings if can't access ioreg */ - if ([sd->extra[0] rangeOfString:@"M1"].location != NSNotFound) { - if ([sd->extra[0] rangeOfString:@"M1 Pro"].location != NSNotFound) - [sd->extra addObject:@"T6000"]; - else if ([sd->extra[0] rangeOfString:@"M1 Max"].location != NSNotFound) - [sd->extra addObject:@"T6001"]; - else if ([sd->extra[0] rangeOfString:@"M1 Ultra"].location != NSNotFound) - [sd->extra addObject:@"T6002"]; - else - [sd->extra addObject:@"T8103"]; - } else if ([sd->extra[0] rangeOfString:@"M2"].location != NSNotFound) - if ([sd->extra[0] rangeOfString:@"M2 Pro"].location != NSNotFound) - [sd->extra addObject:@"T6020"]; - else if ([sd->extra[0] rangeOfString:@"M2 Max"].location != NSNotFound) - [sd->extra addObject:@"T6021"]; - else if ([sd->extra[0] rangeOfString:@"M2 Ultra"].location != NSNotFound) - [sd->extra addObject:@"T6022"]; - else - [sd->extra addObject:@"T8112"]; - else - [sd->extra addObject:@"T****"]; -} - -/* - * find micro archs from ioreg - */ -void generateMicroArchs(static_data* sd) -{ - io_registry_entry_t service; - NSData * data; - - const unsigned char * ecpu_microarch; - const unsigned char * pcpu_microarch; - - int cores = [sd->cluster_core_counts[0] intValue] + [sd->cluster_core_counts[1] intValue] - 1; - - if ((service = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/AppleARMPE/cpu0"))) { - if ((data = (__bridge NSData *)(CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("compatible"), kCFAllocatorDefault, 0))) - ecpu_microarch = [data bytes]; - else - goto error; - } else - goto error; - - if ((service = IORegistryEntryFromPath(kIOMasterPortDefault, - [[NSString stringWithFormat:@"IOService:/AppleARMPE/cpu%d", cores] UTF8String]))) - { - if ((data = (__bridge NSData *)(CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("compatible"), kCFAllocatorDefault, 0))) - pcpu_microarch = [data bytes]; - else - goto error; - } else - goto error; - - [sd->extra addObject:[[[NSString stringWithFormat:@"%s", ecpu_microarch] - componentsSeparatedByString:@","][1] capitalizedString]]; - [sd->extra addObject:[[[NSString stringWithFormat:@"%s", pcpu_microarch] - componentsSeparatedByString:@","][1] capitalizedString]]; - - return; - -error: - /* find the mirco arch using stored strings if can't access ioreg */ - if ([sd->extra[0] rangeOfString:@"M1"].location != NSNotFound) { - [sd->extra addObject:@"Icestorm"]; - [sd->extra addObject:@"Firestorm"]; - } else if ([sd->extra[0] rangeOfString:@"M2"].location != NSNotFound) { - [sd->extra addObject:@"Blizzard"]; - [sd->extra addObject:@"Avalanche"]; - } else { - [sd->extra addObject:@"Unknown"]; - [sd->extra addObject:@"Unknown"]; - } -} - -/* - * find cpu model name - */ -void generateProcessorName(static_data* sd) -{ - size_t len = 32; - char* cpubrand = malloc(len); - sysctlbyname("machdep.cpu.brand_string", cpubrand, &len, NULL, 0); - - if (strcmp(cpubrand, "") != 0) - [sd->extra addObject:[NSString stringWithFormat:@"%s", cpubrand, nil]]; - else - [sd->extra addObject:@"Unknown SoC"]; - - free(cpubrand); -}