Adding code
This commit is contained in:
		
							parent
							
								
									07b76a7fe9
								
							
						
					
					
						commit
						110226ee18
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					zen-rapl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ---> C
 | 
					# ---> C
 | 
				
			||||||
# Prerequisites
 | 
					# Prerequisites
 | 
				
			||||||
*.d
 | 
					*.d
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					MIT License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2018-2020 Ondrej Čerman
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
							
								
								
									
										57
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								README.md
									
									
									
									
									
								
							@ -1,3 +1,58 @@
 | 
				
			|||||||
# zen-rapl
 | 
					# zen-rapl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Advanced monitoring of core power and frequencies on AMD Zen/Epyc processors using MSR.
 | 
					Advanced monitoring of core power and frequencies on AMD Zen processors using MSR.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This uses model-specific registers (MSRs) to read the running average power levels (RAPL) the processor.  It is designed to compliment the [Zenpower3 driver](https://github.com/koweda/zenpower3).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The output has been formatted to resemble those from the `sensors` utility so scripts that use the output from that command can parse it the same.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Example output
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					zen3-rapl
 | 
				
			||||||
 | 
					Package:       109.59 W
 | 
				
			||||||
 | 
					Core_0:          4.50 W
 | 
				
			||||||
 | 
					Core_1:          5.02 W
 | 
				
			||||||
 | 
					Core_2:          4.38 W
 | 
				
			||||||
 | 
					Core_3:          4.71 W
 | 
				
			||||||
 | 
					Core_4:          3.60 W
 | 
				
			||||||
 | 
					Core_5:          3.91 W
 | 
				
			||||||
 | 
					Core_6:          3.42 W
 | 
				
			||||||
 | 
					Core_7:          4.00 W
 | 
				
			||||||
 | 
					Core_8:          1.20 W
 | 
				
			||||||
 | 
					Core_9:          2.46 W
 | 
				
			||||||
 | 
					Core_10:         2.26 W
 | 
				
			||||||
 | 
					Core_11:         2.44 W
 | 
				
			||||||
 | 
					Core_12:         0.97 W
 | 
				
			||||||
 | 
					Core_13:         1.62 W
 | 
				
			||||||
 | 
					Core_14:         0.08 W
 | 
				
			||||||
 | 
					Core_15:         1.52 W
 | 
				
			||||||
 | 
					Core_0_eff:   4.600 GHz
 | 
				
			||||||
 | 
					Core_1_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_2_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_3_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_4_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_5_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_6_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_7_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_8_eff:   3.680 GHz
 | 
				
			||||||
 | 
					Core_9_eff:   4.600 GHz
 | 
				
			||||||
 | 
					Core_10_eff:  3.680 GHz
 | 
				
			||||||
 | 
					Core_11_eff:  3.680 GHz
 | 
				
			||||||
 | 
					Core_12_eff:  3.680 GHz
 | 
				
			||||||
 | 
					Core_13_eff:  3.680 GHz
 | 
				
			||||||
 | 
					Core_14_eff:  3.680 GHz
 | 
				
			||||||
 | 
					Core_15_eff:  3.680 GHz
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Requirements
 | 
				
			||||||
 | 
					* AMD family 17h or 19h processor (Zen, Zen2, Zen3)
 | 
				
			||||||
 | 
					* MSR kernel module (`modprobe msr`)
 | 
				
			||||||
 | 
					* Access to the MSR device files at `/dev/cpu/*/msr` (usually requires root)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Building
 | 
				
			||||||
 | 
					1. `make`
 | 
				
			||||||
 | 
					2. `sudo ./zen-rapl`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Acknowlegements
 | 
				
			||||||
 | 
					Based upon some code from [Zenmonitor 3](https://github.com/jpr999/zenmonitor3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					.PHONY : clean debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LDLIBS = -lm
 | 
				
			||||||
 | 
					objects = zen-rapl.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					zen-rapl : $(objects)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					debug : CFLAGS += -g
 | 
				
			||||||
 | 
					debug : zen-rapl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean :
 | 
				
			||||||
 | 
						rm zen-rapl $(objects)
 | 
				
			||||||
							
								
								
									
										277
									
								
								zen-rapl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								zen-rapl.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,277 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					#include <cpuid.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AMD_STRING "AuthenticAMD"
 | 
				
			||||||
 | 
					#define ZEN_FAMILY 0x17
 | 
				
			||||||
 | 
					#define ZEN3_FAMILY 0x19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MESUREMENT_TIME 0.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int cores = 0;
 | 
				
			||||||
 | 
					static double energy_unit = 0;
 | 
				
			||||||
 | 
					static struct cpudev *cpu_dev_ids;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int *msr_files = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long package_eng_b = 0;
 | 
				
			||||||
 | 
					static unsigned long package_eng_a = 0;
 | 
				
			||||||
 | 
					static unsigned long *core_eng_b = NULL;
 | 
				
			||||||
 | 
					static unsigned long *core_eng_a = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float package_power;
 | 
				
			||||||
 | 
					float *core_power;
 | 
				
			||||||
 | 
					float *core_fid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cpudev {
 | 
				
			||||||
 | 
						short coreid;
 | 
				
			||||||
 | 
						short cpuid;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int check_zen() {
 | 
				
			||||||
 | 
					    unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0, ext_family;
 | 
				
			||||||
 | 
					    char vendor[13];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __get_cpuid(0, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(vendor, &ebx, 4);
 | 
				
			||||||
 | 
					    memcpy(vendor+4, &edx, 4);
 | 
				
			||||||
 | 
					    memcpy(vendor+8, &ecx, 4);
 | 
				
			||||||
 | 
					    vendor[12] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (strcmp(vendor, AMD_STRING) != 0){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __get_cpuid(1, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ext_family = ((eax >> 8) & 0xF) + ((eax >> 20) & 0xFF);
 | 
				
			||||||
 | 
					    if (ext_family != ZEN_FAMILY && ext_family != ZEN3_FAMILY){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int get_core_count() {
 | 
				
			||||||
 | 
					    unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
 | 
				
			||||||
 | 
					    unsigned int logical_cpus, threads_per_code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // AMD PPR: page 57 - CPUID_Fn00000001_EBX
 | 
				
			||||||
 | 
					    __get_cpuid(1, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					    logical_cpus = (ebx >> 16) & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // AMD PPR: page 82 - CPUID_Fn8000001E_EBX
 | 
				
			||||||
 | 
					    __get_cpuid(0x8000001E, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					    threads_per_code = ((ebx >> 8) & 0xF) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (threads_per_code == 0)
 | 
				
			||||||
 | 
					        return logical_cpus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return logical_cpus / threads_per_code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct cpudev* get_cpu_dev_ids() {
 | 
				
			||||||
 | 
					    unsigned int num_cores = get_core_count();
 | 
				
			||||||
 | 
					    struct cpudev* cores = malloc(num_cores * sizeof(struct cpudev));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < num_cores; ++i) {
 | 
				
			||||||
 | 
					        cores[i].coreid = i;
 | 
				
			||||||
 | 
					        cores[i].cpuid = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DIR* d;
 | 
				
			||||||
 | 
					    struct dirent* dir;
 | 
				
			||||||
 | 
					    d = opendir("/sys/devices/system/cpu");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (d) {
 | 
				
			||||||
 | 
					        while ((dir = readdir(d)) != NULL) {
 | 
				
			||||||
 | 
					            if (strncmp(dir->d_name, "cpu", 3) == 0 && atoi(dir->d_name + 3) > 0) {
 | 
				
			||||||
 | 
					                char path[256];
 | 
				
			||||||
 | 
									int core_id;
 | 
				
			||||||
 | 
									FILE* f;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									snprintf(path, sizeof(path), "/sys/devices/system/cpu/%s/topology/core_id", dir->d_name);
 | 
				
			||||||
 | 
									f = fopen(path, "r");
 | 
				
			||||||
 | 
									if (f) {
 | 
				
			||||||
 | 
										fscanf(f, "%d", &core_id);
 | 
				
			||||||
 | 
										fclose(f);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
					                snprintf(path, sizeof(path), "/sys/devices/system/cpu/%s/topology/thread_siblings_list", dir->d_name);
 | 
				
			||||||
 | 
					                f = fopen(path, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (f) {
 | 
				
			||||||
 | 
					                    int cpuid, sibling;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (fscanf(f, "%d,%d", &cpuid, &sibling) == 2) {
 | 
				
			||||||
 | 
					                        // The lower numbered CPU is considered the representative of the core
 | 
				
			||||||
 | 
					                        if (cores[core_id].cpuid == -1 || cores[core_id].cpuid > cpuid) {
 | 
				
			||||||
 | 
					                            cores[core_id].cpuid = cpuid;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    fclose(f);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        closedir(d);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return cores;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int open_msr(short devid) {
 | 
				
			||||||
 | 
					    char msr_path[20];
 | 
				
			||||||
 | 
					    sprintf(msr_path, "/dev/cpu/%d/msr", devid);
 | 
				
			||||||
 | 
					    return open(msr_path, O_RDONLY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int read_msr(int file, unsigned int index, unsigned long long *data) {
 | 
				
			||||||
 | 
					    if (file < 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pread(file, data, sizeof *data, index) == sizeof *data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static double get_energy_unit() {
 | 
				
			||||||
 | 
					    unsigned long long data;
 | 
				
			||||||
 | 
					    // AMD OSRR: page 139 - MSRC001_0299
 | 
				
			||||||
 | 
					    if (!read_msr(msr_files[0], 0xC0010299, &data))
 | 
				
			||||||
 | 
					        return 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pow(1.0/2.0, (double)((data >> 8) & 0x1F));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long get_package_energy() {
 | 
				
			||||||
 | 
					    unsigned long long data;
 | 
				
			||||||
 | 
					    // AMD OSRR: page 139 - MSRC001_029B
 | 
				
			||||||
 | 
					    if (!read_msr(msr_files[0], 0xC001029B, &data))
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long get_core_energy(int core) {
 | 
				
			||||||
 | 
					    unsigned long long data;
 | 
				
			||||||
 | 
					    // AMD OSRR: page 139 - MSRC001_029A
 | 
				
			||||||
 | 
					    if (!read_msr(msr_files[core], 0xC001029A, &data))
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static double get_core_fid(int core) {
 | 
				
			||||||
 | 
					    double ratio;
 | 
				
			||||||
 | 
					    unsigned long long data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // By reverse-engineering Ryzen Master, we know that
 | 
				
			||||||
 | 
					    //  this undocumented MSR is responsible for returning
 | 
				
			||||||
 | 
					    //  the FID and FDID for the core used for calculating the
 | 
				
			||||||
 | 
					    //  effective frequency.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // The FID is returned in bits [8:0]
 | 
				
			||||||
 | 
					    // The FDID is returned in bits [14:8]
 | 
				
			||||||
 | 
					    if (!read_msr(msr_files[core], 0xC0010293, &data))
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ratio = (double)(data & 0xff) / (double)((data >> 8) & 0x3F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The effective ratio is based on increments of 200 MHz.
 | 
				
			||||||
 | 
					    return ratio * 200.0 / 1000.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int msr_init() {
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!check_zen())
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cores = get_core_count();
 | 
				
			||||||
 | 
					    if (cores == 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpu_dev_ids = get_cpu_dev_ids();
 | 
				
			||||||
 | 
					    msr_files = malloc(cores * sizeof (int));
 | 
				
			||||||
 | 
					    for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
					        msr_files[i] = open_msr(cpu_dev_ids[i].cpuid);
 | 
				
			||||||
 | 
							if (msr_files[i] < 0)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    energy_unit = get_energy_unit();
 | 
				
			||||||
 | 
					    if (energy_unit == 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core_eng_b = malloc(cores * sizeof (unsigned long));
 | 
				
			||||||
 | 
					    core_eng_a = malloc(cores * sizeof (unsigned long));
 | 
				
			||||||
 | 
					    core_power = malloc(cores * sizeof (float));
 | 
				
			||||||
 | 
					    core_fid = malloc(cores * sizeof (float));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /*msr_update();*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void msr_update() {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    package_eng_b = get_package_energy();
 | 
				
			||||||
 | 
					    for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
					        core_eng_b[i] = get_core_energy(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    usleep(MESUREMENT_TIME*1000000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    package_eng_a = get_package_energy();
 | 
				
			||||||
 | 
					    for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
					        core_eng_a[i] = get_core_energy(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (package_eng_a >= package_eng_b) {
 | 
				
			||||||
 | 
					        package_power = (package_eng_a - package_eng_b) * energy_unit / MESUREMENT_TIME;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
					        if (core_eng_a[i] >= core_eng_b[i]) {
 | 
				
			||||||
 | 
					            core_power[i] = (core_eng_a[i] - core_eng_b[i]) * energy_unit / MESUREMENT_TIME;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        core_fid[i] = get_core_fid(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
						int init_ok, i;
 | 
				
			||||||
 | 
						init_ok = msr_init();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (init_ok) {
 | 
				
			||||||
 | 
							msr_update();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							printf("Error reading RAPL (running average power limit) sensors.\nAre you root? Did you `modprobe msr`? Are you on AMD Zen?\n");
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("zen3-rapl\n");
 | 
				
			||||||
 | 
						printf("%-12s   %6.2f W\n", "Package:", package_power);
 | 
				
			||||||
 | 
						char core_name[256];
 | 
				
			||||||
 | 
						/* Print core powers */
 | 
				
			||||||
 | 
						for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
							sprintf(core_name, "Core_%d:", i);
 | 
				
			||||||
 | 
							printf("%-12s   %6.2f W\n", core_name, i, core_power[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						/* Print core effective frequencies */
 | 
				
			||||||
 | 
						for (i = 0; i < cores; i++) {
 | 
				
			||||||
 | 
							sprintf(core_name, "Core_%d_eff:", i);
 | 
				
			||||||
 | 
							printf("%-12s %6.3f GHz\n", core_name, i, core_fid[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user