@@ -503,13 +503,30 @@ func parseCPUMetrics(powermetricsOutput string, cpuMetrics CPUMetrics) CPUMetric
503503 residencyRe := regexp .MustCompile (`(\w+-Cluster)\s+HW active residency:\s+(\d+\.\d+)%` )
504504 frequencyRe := regexp .MustCompile (`(\w+-Cluster)\s+HW active frequency:\s+(\d+)\s+MHz` )
505505
506+ const numReadings = 5
507+ var pClusterReadings []int
508+ var pClusterFreqReadings []int
506509 for _ , line := range lines {
507510 residencyMatches := residencyRe .FindStringSubmatch (line )
508511 frequencyMatches := frequencyRe .FindStringSubmatch (line )
509512
510513 if residencyMatches != nil {
511514 cluster := residencyMatches [1 ]
512515 percent , _ := strconv .ParseFloat (residencyMatches [2 ], 64 )
516+ switch cluster {
517+ case "E0-Cluster" :
518+ cpuMetrics .E0ClusterActive = int (percent )
519+ case "E1-Cluster" :
520+ cpuMetrics .E1ClusterActive = int (percent )
521+ case "P0-Cluster" :
522+ cpuMetrics .P0ClusterActive = int (percent )
523+ case "P1-Cluster" :
524+ cpuMetrics .P1ClusterActive = int (percent )
525+ case "P2-Cluster" :
526+ cpuMetrics .P2ClusterActive = int (percent )
527+ case "P3-Cluster" :
528+ cpuMetrics .P3ClusterActive = int (percent )
529+ }
513530 if strings .HasPrefix (cluster , "E" ) {
514531 eClusterActiveTotal += int (percent )
515532 eClusterCount ++
@@ -522,12 +539,31 @@ func parseCPUMetrics(powermetricsOutput string, cpuMetrics CPUMetrics) CPUMetric
522539 if frequencyMatches != nil {
523540 cluster := frequencyMatches [1 ]
524541 freqMHz , _ := strconv .Atoi (frequencyMatches [2 ])
542+ switch cluster {
543+ case "E0-Cluster" :
544+ cpuMetrics .E0ClusterFreqMHz = freqMHz
545+ case "E1-Cluster" :
546+ cpuMetrics .E1ClusterFreqMHz = freqMHz
547+ case "P0-Cluster" :
548+ cpuMetrics .P0ClusterFreqMHz = freqMHz
549+ case "P1-Cluster" :
550+ cpuMetrics .P1ClusterFreqMHz = freqMHz
551+ case "P2-Cluster" :
552+ cpuMetrics .P2ClusterFreqMHz = freqMHz
553+ case "P3-Cluster" :
554+ cpuMetrics .P3ClusterFreqMHz = freqMHz
555+ }
525556 if strings .HasPrefix (cluster , "E" ) {
526557 eClusterFreqTotal += int (freqMHz )
527558 cpuMetrics .EClusterFreqMHz = eClusterFreqTotal
528559 } else if strings .HasPrefix (cluster , "P" ) {
529560 pClusterFreqTotal += int (freqMHz )
530561 cpuMetrics .PClusterFreqMHz = pClusterFreqTotal
562+ pClusterFreqReadings = append (pClusterFreqReadings , freqMHz )
563+ if len (pClusterFreqReadings ) > numReadings {
564+ pClusterFreqReadings = pClusterFreqReadings [1 :] // Remove the oldest reading
565+ }
566+ cpuMetrics .PClusterFreqMHz = average (pClusterFreqReadings )
531567 }
532568 }
533569
@@ -571,17 +607,30 @@ func parseCPUMetrics(powermetricsOutput string, cpuMetrics CPUMetrics) CPUMetric
571607 cpuMetrics .ECores = eCores
572608 cpuMetrics .PCores = pCores
573609
610+ // Calculate average P-Cluster Active using a moving average
611+ currentPActive := (cpuMetrics .P0ClusterActive + cpuMetrics .P1ClusterActive + cpuMetrics .P2ClusterActive + cpuMetrics .P3ClusterActive ) / 4
612+ pClusterReadings = append (pClusterReadings , currentPActive )
613+ if len (pClusterReadings ) > numReadings {
614+ pClusterReadings = pClusterReadings [1 :] // Remove the oldest reading
615+ }
616+ cpuMetrics .PClusterActive = average (pClusterReadings )
617+
574618 // Calculate average active residency and frequency for E and P clusters
575619 if eClusterCount > 0 {
576620 cpuMetrics .EClusterActive = eClusterActiveTotal / eClusterCount
577621 }
578- if pClusterCount > 0 {
579- cpuMetrics .PClusterActive = pClusterActiveTotal / pClusterCount
580- }
581622
582623 return cpuMetrics
583624}
584625
626+ func average (nums []int ) int {
627+ sum := 0
628+ for _ , num := range nums {
629+ sum += num
630+ }
631+ return sum / len (nums )
632+ }
633+
585634func parseGPUMetrics (powermetricsOutput string , gpuMetrics GPUMetrics ) GPUMetrics {
586635 re := regexp .MustCompile (`GPU HW active residency:\s+(\d+\.\d+)%` ) // Regex to capture the floating-point number followed by '%'
587636 lines := strings .Split (powermetricsOutput , "\n " )
0 commit comments