From b2cffa8620be0e60b2b7e70cc887e4dab9e54798 Mon Sep 17 00:00:00 2001 From: Gary Corrall <4834451+gcorrall@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:57:44 +0000 Subject: [PATCH 1/2] Handle when the energy counter (energy_uj) wraps around (reaches max_energy_range_uj) when using Intel RAPL --- src/intel_rapl_sysfs.adb | 22 ++++++++++++++++++++++ src/intel_rapl_sysfs.ads | 5 +++++ src/powerjoular.adb | 35 +++++++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/intel_rapl_sysfs.adb b/src/intel_rapl_sysfs.adb index b186b6c..a38f77f 100644 --- a/src/intel_rapl_sysfs.adb +++ b/src/intel_rapl_sysfs.adb @@ -87,4 +87,26 @@ package body Intel_RAPL_sysfs is --Put_Line ("Error reading file " & Package_Name & " for Intel RAPL."); end; + procedure Get_Max_Energy_Range (RAPL_Data : in out Intel_RAPL_Data; Package_Name : in String) is + F_Name : File_Type; -- File handle + Folder_Name : constant String := "/sys/class/powercap/intel-rapl/"; -- Folder prefix for file to read + begin + if (Package_Name = "psys") then + Open (F_Name, In_File, Folder_Name & "intel-rapl:1/max_energy_range_uj"); + RAPL_Data.max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; + Close (F_Name); + elsif (Package_Name = "pkg") then + Open (F_Name, In_File, Folder_Name & "intel-rapl:0/max_energy_range_uj"); + RAPL_Data.max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; + Close (F_Name); + elsif (Package_Name = "dram") then + Open (F_Name, In_File, Folder_Name & "intel-rapl:0/intel-rapl:0:2/max_energy_range_uj"); + RAPL_Data.dram_max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; + Close (F_Name); + end if; + exception + when others => + return; + end; + end Intel_RAPL_sysfs; diff --git a/src/intel_rapl_sysfs.ads b/src/intel_rapl_sysfs.ads index 17fb631..0cece77 100644 --- a/src/intel_rapl_sysfs.ads +++ b/src/intel_rapl_sysfs.ads @@ -26,6 +26,10 @@ package Intel_RAPL_sysfs is psys_supported : Boolean := False; -- if system supports psys pkg_supported : Boolean := False; -- if system supports pkg 0 dram_supported : Boolean := False; -- if system support dram 0 + + -- Data to store max energy ranges + max_energy_range : Long_Float := 0.0; -- max_energy_range_uj + dram_max_energy_range : Long_Float := 0.0; -- dram max_energy_range_uj end record; -- Calculate total energy consumption from Linux powercap sysfs @@ -38,4 +42,5 @@ package Intel_RAPL_sysfs is -- So far, only package 0 is supported (and dram in package 0) procedure Check_Supported_Packages (RAPL_Data : in out Intel_RAPL_Data; Package_Name : in String); + procedure Get_Max_Energy_Range (RAPL_Data : in out Intel_RAPL_Data; Package_Name : in String); end Intel_RAPL_sysfs; diff --git a/src/powerjoular.adb b/src/powerjoular.adb index d281189..7ad09e4 100644 --- a/src/powerjoular.adb +++ b/src/powerjoular.adb @@ -167,18 +167,28 @@ begin if Check_Intel_Supported_System (Platform_Name) then -- For Intel RAPL, check and populate supported packages first Check_Supported_Packages (RAPL_Before, "psys"); - if RAPL_Before.psys_supported and Show_Debug then - Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL psys: " & Boolean'Image (RAPL_Before.Psys_Supported)); + + if RAPL_Before.psys_supported then + Get_Max_Energy_Range (RAPL_Before, "psys"); + if Show_Debug then + Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL psys: " & Boolean'Image (RAPL_Before.Psys_Supported)); + end if; end if; if (not RAPL_Before.psys_supported) then -- Only check for pkg and dram if psys is not supported Check_Supported_Packages (RAPL_Before, "pkg"); Check_Supported_Packages (RAPL_Before, "dram"); - if RAPL_Before.Pkg_Supported and Show_Debug then - Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL pkg: " & Boolean'Image (RAPL_Before.pkg_supported)); + if RAPL_Before.Pkg_Supported then + Get_Max_Energy_Range (RAPL_Before, "pkg"); + if Show_Debug then + Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL pkg: " & Boolean'Image (RAPL_Before.pkg_supported)); + end if; end if; - if RAPL_Before.Dram_Supported and Show_Debug then - Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL dram: " & Boolean'Image (RAPL_Before.Dram_Supported)); + if RAPL_Before.Dram_Supported then + Get_Max_Energy_Range (RAPL_Before, "dram"); + if Show_Debug then + Put_Line (Ada.Characters.Latin_1.HT & "Intel RAPL dram: " & Boolean'Image (RAPL_Before.Dram_Supported)); + end if; end if; end if; RAPL_After := RAPL_Before; -- Populate the "after" data type with same checking as the "before" (insteaf of wasting redundant calls to procedure) @@ -257,6 +267,19 @@ begin if Check_Intel_Supported_System (Platform_Name) then -- Calculate Intel RAPL energy consumption RAPL_Energy := RAPL_After.total_energy - RAPL_Before.total_energy; + + if RAPL_Before.Dram_supported then + if RAPL_Before.dram > RAPL_After.dram then + -- dram has wrapped + RAPL_Energy := RAPL_Energy + RAPL_Before.dram_max_energy_range; + end if; + end if; + + if RAPL_Before.total_energy > RAPL_After.total_energy then + -- energy has wrapped + RAPL_Energy := RAPL_Energy + RAPL_Before.max_energy_range; + end if; + CPU_Power := RAPL_Energy; Total_Power := CPU_Power; end if; From 563a8c903cc433144e18a637a0c127d5d18a94b5 Mon Sep 17 00:00:00 2001 From: Gary Corrall <4834451+gcorrall@users.noreply.github.com> Date: Fri, 23 Feb 2024 11:35:25 +0000 Subject: [PATCH 2/2] Have distinct variables for psys and pkg max_energy_range --- src/intel_rapl_sysfs.adb | 4 ++-- src/intel_rapl_sysfs.ads | 3 ++- src/powerjoular.adb | 16 ++++++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/intel_rapl_sysfs.adb b/src/intel_rapl_sysfs.adb index a38f77f..381b4cd 100644 --- a/src/intel_rapl_sysfs.adb +++ b/src/intel_rapl_sysfs.adb @@ -93,11 +93,11 @@ package body Intel_RAPL_sysfs is begin if (Package_Name = "psys") then Open (F_Name, In_File, Folder_Name & "intel-rapl:1/max_energy_range_uj"); - RAPL_Data.max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; + RAPL_Data.psys_max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; Close (F_Name); elsif (Package_Name = "pkg") then Open (F_Name, In_File, Folder_Name & "intel-rapl:0/max_energy_range_uj"); - RAPL_Data.max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; + RAPL_Data.pkg_max_energy_range := Long_Float'Value (Get_Line (F_Name)) / 1000000.0; Close (F_Name); elsif (Package_Name = "dram") then Open (F_Name, In_File, Folder_Name & "intel-rapl:0/intel-rapl:0:2/max_energy_range_uj"); diff --git a/src/intel_rapl_sysfs.ads b/src/intel_rapl_sysfs.ads index 0cece77..368c5b5 100644 --- a/src/intel_rapl_sysfs.ads +++ b/src/intel_rapl_sysfs.ads @@ -28,7 +28,8 @@ package Intel_RAPL_sysfs is dram_supported : Boolean := False; -- if system support dram 0 -- Data to store max energy ranges - max_energy_range : Long_Float := 0.0; -- max_energy_range_uj + pkg_max_energy_range : Long_Float := 0.0; -- pkg max_energy_range_uj + psys_max_energy_range : Long_Float := 0.0; -- psys max_energy_range_uj dram_max_energy_range : Long_Float := 0.0; -- dram max_energy_range_uj end record; diff --git a/src/powerjoular.adb b/src/powerjoular.adb index 7ad09e4..9f083c2 100644 --- a/src/powerjoular.adb +++ b/src/powerjoular.adb @@ -268,18 +268,22 @@ begin -- Calculate Intel RAPL energy consumption RAPL_Energy := RAPL_After.total_energy - RAPL_Before.total_energy; - if RAPL_Before.Dram_supported then + if RAPL_Before.total_energy > RAPL_After.total_energy then + -- energy has wrapped + if RAPL_Before.psys_supported then + RAPL_Energy := RAPL_Energy + RAPL_Before.psys_max_energy_range; + elsif RAPL_Before.Pkg_Supported then + RAPL_Energy := RAPL_Energy + RAPL_Before.pkg_max_energy_range; + end if; + end if; + + if RAPL_Before.Pkg_Supported and RAPL_Before.Dram_supported then if RAPL_Before.dram > RAPL_After.dram then -- dram has wrapped RAPL_Energy := RAPL_Energy + RAPL_Before.dram_max_energy_range; end if; end if; - if RAPL_Before.total_energy > RAPL_After.total_energy then - -- energy has wrapped - RAPL_Energy := RAPL_Energy + RAPL_Before.max_energy_range; - end if; - CPU_Power := RAPL_Energy; Total_Power := CPU_Power; end if;