Proposal: present a Notebook that includes and describes python scripts using the pandas and numpy libraries, for the processing and analysis of the log data generated in the experiments of characterization of power consumption in multicores
from IPython.display import Image
import pandas as pd
from os import walk
%pylab inline
import re
import matplotlib.pyplot as plt
plt.rc('legend', fontsize='small')
from mpl_toolkits.mplot3d import Axes3D
from IPython.display import display, HTML
from datetime import timedelta
from __future__ import print_function, division
import statsmodels.formula.api as smf
import pylab as pl
pd.set_option('precision', 2)
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.tools import FigureFactory as FF
import scipy
This work aims to enhance the data processing of my thesis as well as generating a jupyter notebook with clear exposure of the results.
One of the activities of the thesis is collecting information of power consumption of computers (hosts) while benchmarks are executed. The goal is the characterization of power consumption regarding of computing resource type utilized and the utilization level, this is, the used percentage of the host capacity.
The following infrastructure is used:
Benchmarks are executed in host while a script is polling the power meter (PDU) and logging the consumption information. There are three types of benchmarks each one oriented to a particular computational resource (CPU, memory or disk). The benchmarks are executed individually and combined, and also with different utilization levels.
An experiment consists of one or several types of benchmarks, executing, at a certain utilization level. For example, the experiment "c1l37y5" corresponds to the CPU-bound benchmark running with a utilization level of 35.5% and the experiment "c1f1l2525" corresponds to the CPU-bound benchmark running combined with the disk-bound benchmark, both with a utilization level of 25%.
Each experiments is executed 20 times for statistical validity.
There are two data sources to process. On the one hand the power consumption (written in logging machine) and on the other the start and end of the benchmarks executions (written in host). By comparing the datetime of both sources, it is possible to know how much energy the execution of a process consumed.
This information is registered polling every one second on the power meter and registering the instant power measured in a text file. In the following code lines the logs of each day are concatenated in the same dataframe (cleanDfEnergyLog). The relevant fields are "datetime" and instant power "P(W)". The format of power log files is the following:
|datetime|Timestamp (local to the python script)|I(amps)|P(W)|F(mm/dd/aaaa)|H(hh/mm/ss)|Device Load (amps)|Bank 1 Load (amps)|Bank 2 Load (amps)|P(W/VA)|Power factor|Peak Load(W)|Fecha del Peak Load|Hora del Peak Load|E(KWh)|Fecha desde que se cuenta E|Hora desde que se cuenta E|Voltaje(V)|Frecuencia(Hz)|
|2016-08-30 00:00:00|1472526000.47|0.84|182|08/30/2016|02:54:37|0.84|0.84|0.00|182/192|0.947|1.82|02/07/2016|16:08:39|1120.5|12/16/2015|12:08:30|229.0|50.0|
|2016-08-30 00:00:01|1472526001.65|0.85|183|08/30/2016|02:54:38|0.85|0.85|0.00|183/195|0.938|1.82|02/07/2016|16:08:39|1120.5|12/16/2015|12:08:30|229.0|50.0|
#Collecting power log files from disk
POW_DIR = "milab_files/energy_logs/"
list_of_file_names= next(walk(POW_DIR))[2]
dfEnergyLog = pd.DataFrame()
for file_name in list_of_file_names[:]:
dfEnergyLogAux=pd.read_csv(POW_DIR + file_name, sep='|')
dfEnergyLog = dfEnergyLog.append(dfEnergyLogAux)
#Cleaning (deleting rows without date format, that is: headers, broken lines)
r = re.compile('([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})')
cleanDfEnergyLog = dfEnergyLog[['datetime','P(W)']][dfEnergyLog.datetime.str.match(r).str.len()>0]
#Converting to appropriate types
cleanDfEnergyLog['datetime'] = pd.to_datetime(cleanDfEnergyLog['datetime'][:]
, format='%Y-%m-%d %H:%M:%S')
cleanDfEnergyLog['P(W)'] = pd.to_numeric(cleanDfEnergyLog['P(W)'])
#Showing result
cleanDfEnergyLog[['datetime','P(W)']].head()
When a benchmark execution begins or ends, an empty text file is created. The filename contains the info:
The format of execution log filemanes is the following:
c1f1l2525_20160912235624996_2016|09|12-23:56:25:001.ini
In the following lines of code the execution logs are collected and grouped by modality-host in dataframes. Each line of the dataframes corresponds to one benchmark execution (it indicates the start and the end)
#Collecting execution logs files from disk
def collectExecutionLogs(EXE_DIR):
list_of_file_names= next(walk(EXE_DIR))[2]
df_exe = pd.DataFrame(list_of_file_names)
#Separating the name of the file in columns by split
df_exe.columns = ['data']
df_exe = pd.DataFrame(df_exe.data.str.split('_').tolist(), columns = ['cod','run','data'])
df_exe_aux = pd.DataFrame(df_exe.data.str.split('.').tolist(), columns = ['datetime','inifin'])
df_exe['inifin'] = df_exe_aux['inifin']
#Truncating milliseconds, they are unnecessary
df_exe['datetime'] = df_exe_aux['datetime'].str.slice(0,-4)
#Converting to appropriate types
df_exe['datetime'] = pd.to_datetime(df_exe['datetime'][:]
, format='%Y|%m|%d-%H:%M:%S')
#merging and filtering to get one execution per row
df_exe_merged = pd.merge(df_exe, df_exe, on='run')[['cod_x','run','datetime_x','inifin_x','datetime_y','inifin_y']]
df_exe_filtered = df_exe_merged[df_exe_merged.inifin_x=='ini'][df_exe_merged.inifin_y=='end']
return df_exe_filtered
df_exe_energy_single_intel = collectExecutionLogs("milab_files/executions/energy/single/intel");
df_exe_energy_single_amd = collectExecutionLogs("milab_files/executions/energy/single/amd");
df_exe_energy_double_intel = collectExecutionLogs("milab_files/executions/energy/double/intel");
df_exe_energy_double_amd = collectExecutionLogs("milab_files/executions/energy/double/amd");
df_exe_energy_triple_intel = collectExecutionLogs("milab_files/executions/energy/triple/intel");
df_exe_energy_triple_amd = collectExecutionLogs("milab_files/executions/energy/triple/amd");
#Showing result example
df_exe_energy_triple_amd.head()
Over the dataframes of the benchmark execution it is neccesary to execute the following operations to facilitate the visualization and analysis:
In the following segments of code this operations are executed:
#experiment cod to benchmark code
def cod2bkcod(cod):
if 'c1m2f1' in cod:
return 'c1m2f1'
if 'c1m2' in cod:
return 'c1m2'
if 'm2f1' in cod:
return 'm2f1'
if 'c1f1' in cod:
return 'c1f1'
if 'm2' in cod:
return 'm2'
if "c1" in cod:
return 'c1'
if "f1" in cod:
return 'f1'
#experiment cod to utilization level. First coordinate
def cod2ULx(cod):
if "252525" in cod:
return 25
if "252550" in cod:
return 25
if "255025" in cod:
return 25
if "502525" in cod:
return 50
if "2525" in cod:
return 25
if "2550" in cod:
return 25
if "2575" in cod:
return 25
if "5025" in cod:
return 50
if "5050" in cod:
return 50
if "7525" in cod:
return 75
if '12y5' in cod:
return 12.5
if "25" in cod:
return 25
if "37y5" in cod:
return 37.5
if "50" in cod:
return 50
if "62y5" in cod:
return 62.5
if "75" in cod:
return 75
if "87y5" in cod:
return 87.5
if "100" in cod:
return 100
#experiment cod to utilization level. Second coordinate
def cod2ULy(cod):
if "252525" in cod:
return 25
if "252550" in cod:
return 25
if "255025" in cod:
return 50
if "502525" in cod:
return 25
if "2525" in cod:
return 25
if "2550" in cod:
return 50
if "2575" in cod:
return 75
if "5025" in cod:
return 25
if "5050" in cod:
return 50
if "7525" in cod:
return 25
#experiment cod to utilization level. Thrid coordinate
def cod2ULz(cod):
if "252525" in cod:
return 25
if "252550" in cod:
return 50
if "255025" in cod:
return 25
if "502525" in cod:
return 25
#experiment cod to utilization level and benchmark cod. Single modality
def singleULAndBkCod(df_exe):
df_exe['UL'] = df_exe.apply(lambda x:cod2ULx(x.cod_x),axis = 1)
df_exe['bkcod'] = df_exe.apply(lambda x:cod2bkcod(x.cod_x),axis = 1)
return df_exe
#experiment cod to utilization level and benchmark cod. Double modality
def doubleULAndBkCod(df_exe):
df_exe['ULx'] = df_exe.apply(lambda x:cod2ULx(x.cod_x),axis = 1)
df_exe['ULy'] = df_exe.apply(lambda x:cod2ULy(x.cod_x),axis = 1)
df_exe['bkcod'] = df_exe.apply(lambda x:cod2bkcod(x.cod_x),axis = 1)
return df_exe
#experiment cod to utilization level and benchmark cod. Triple modality
def tripleULAndBkCod(df_exe):
df_exe['ULx'] = df_exe.apply(lambda x:cod2ULx(x.cod_x),axis = 1)
df_exe['ULy'] = df_exe.apply(lambda x:cod2ULy(x.cod_x),axis = 1)
df_exe['ULz'] = df_exe.apply(lambda x:cod2ULz(x.cod_x),axis = 1)
df_exe['bkcod'] = df_exe.apply(lambda x:cod2bkcod(x.cod_x),axis = 1)
return df_exe
df_exe_energy_single_intel = singleULAndBkCod(df_exe_energy_single_intel)
df_exe_energy_single_amd = singleULAndBkCod(df_exe_energy_single_amd)
df_exe_energy_double_intel = doubleULAndBkCod(df_exe_energy_double_intel)
df_exe_energy_double_amd = doubleULAndBkCod(df_exe_energy_double_amd)
df_exe_energy_triple_intel = tripleULAndBkCod(df_exe_energy_triple_intel)
df_exe_energy_triple_amd = tripleULAndBkCod(df_exe_energy_triple_amd)
#TODO
AMD_IDLE_PC = 183.4
INTEL_IDLE_PC = 57.0
The difference in the system time between host and logging machine was registered in each experiment. In the following lines of code, begin and end times of the experiments are fixed with the corresponding offset
# adding offset to begin and end time off the benchmark execution
def addOffset(df_exe,offsetSeconds):
df_exe.datetime_y = \
df_exe.apply(lambda x: pd.to_datetime(x.datetime_y)+pd.Timedelta(seconds=offsetSeconds) ,axis = 1)
df_exe.datetime_x = \
df_exe.apply(lambda x: pd.to_datetime(x.datetime_x)+pd.Timedelta(seconds=offsetSeconds) ,axis = 1)
return df_exe
offsetSeconds = -10810
df_exe_energy_single_intel = addOffset(df_exe_energy_single_intel,offsetSeconds)
offsetSeconds = -11036
df_exe_energy_single_amd = addOffset(df_exe_energy_single_amd,offsetSeconds)
offsetSeconds = -180
df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1m2'] = \
addOffset(df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1m2'],offsetSeconds)
offsetSeconds = -10810
df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1f1'] = \
addOffset(df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1f1'],offsetSeconds)
df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='m2f1'] = \
addOffset(df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='m2f1'],offsetSeconds)
offsetSeconds = -11036
df_exe_energy_double_amd = \
addOffset(df_exe_energy_double_amd,offsetSeconds)
offsetSeconds = -10810
df_exe_energy_triple_intel = \
addOffset(df_exe_energy_triple_intel,offsetSeconds)
offsetSeconds = -180
df_exe_energy_triple_amd = \
addOffset(df_exe_energy_triple_amd,offsetSeconds)
After collecting data from each source, it is neccesary to cross the information to get the power consumption of the benchmark executions. For each experiment, that corresponds to the combination benchmark-modality-utilization level, there are 20 independent executions. The result of the following code are dataframes grouped by modality and host. The rows are the benchmark executions and their power consumption (caculated as the average of the power registered in the logging machine whlie the benchmark is executing)
#add new column "power_average" that is the average
#of power registered between the begins and the end of an execution
def crossing(df_exe):
power_average = []
#power_desv = []
for index, row in df_exe.iterrows():
cleanDfEnergyLogCropSup = cleanDfEnergyLog[row.datetime_y > cleanDfEnergyLog.datetime]
cleanDfEnergyLogCropInfAndSup = cleanDfEnergyLogCropSup[row.datetime_x < cleanDfEnergyLogCropSup.datetime]
aux_mean = cleanDfEnergyLogCropInfAndSup['P(W)'].mean()
#aux_std = cleanDfEnergyLogCropInfAndSup['P(W)'].std()
if aux_mean == 0:
print ("there is a zero")
power_average.append(aux_mean)
#power_desv.append(aux_std)
df_exe['power_average'] = pd.Series(power_average).values
return df_exe
#applying for each modality-host
df_exe_energy_single_intel=crossing(df_exe_energy_single_intel)
df_exe_energy_single_amd=crossing(df_exe_energy_single_amd)
df_exe_energy_double_intel=crossing(df_exe_energy_double_intel)
df_exe_energy_double_amd=crossing(df_exe_energy_double_amd)
df_exe_energy_triple_intel=crossing(df_exe_energy_triple_intel)
df_exe_energy_triple_amd=crossing(df_exe_energy_triple_amd)
#showing result for experiment 'c1l100' as example. the 20 independent executions
display(df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l100'])
#display(df_exe_energy_single_amd)
For complementing the power characterization, performance experiments are executed. In this experiments the same benchmarks, without time limit, are runnnig in different utilization levels. This procedure allows to determine how workload affects the performance for each type of benchmark. Only single modality is considered.
In this case, the filename contains the info:
The format of execution log filemanes is the following:
c1ntl12y5_20170302122631609_c1unt_20170302122631614_2017|03|02-12:26:31:620.ini
The following lines of code collect, clean, convert and merge the information of the performance execution. The result is dataframes grouped by host. The rows are the instances of the benchmark executions.
#COllecting execution log files of performance experiments
def collectPerformanceExecutionLogs(EXE_DIR):
list_of_file_names= next(walk(EXE_DIR))[2]
df_exe = pd.DataFrame(list_of_file_names)
#Separating the name of the file in columns by split
df_exe.columns = ['data']
df_exe = pd.DataFrame(df_exe.data.str.split('_').tolist(), columns = ['cod','exe','codu','instance','data'])
df_exe_aux = pd.DataFrame(df_exe.data.str.split('.').tolist(), columns = ['datetime','inifin'])
#Truncating milliseconds, they are unnecessary
df_exe['datetime'] = df_exe_aux['datetime'].str.slice(0,-4)
df_exe['inifin'] = df_exe_aux['inifin']
#Converting to appropriate types
df_exe['datetime'] = pd.to_datetime(df_exe['datetime'][:]
, format='%Y|%m|%d-%H:%M:%S')
#Merging and filtering to get one execution per row
df_exe_merged = pd.merge(df_exe, df_exe, on=['exe','instance','codu'])\
[['cod_x','codu','exe','instance','datetime_x','inifin_x','cod_y','datetime_y','inifin_y']]
df_exe_filtered = df_exe_merged[df_exe_merged.inifin_x=='ini'][df_exe_merged.inifin_y=='end']
#Calcuating instances duration
df_exe_filtered['time']= df_exe_filtered['datetime_y'] - df_exe_filtered['datetime_x']
df_exe_filtered['seconds']= df_exe_filtered['time'].dt.total_seconds()
return df_exe_filtered
df_exe_performance_single_amd = collectPerformanceExecutionLogs("milab_files/executions/performance/single/amd")
df_exe_performance_single_intel = collectPerformanceExecutionLogs("milab_files/executions/performance/single/intel")
#Obtaining utilization level
df_exe_performance_single_amd = singleULAndBkCod(df_exe_performance_single_amd)
df_exe_performance_single_intel = singleULAndBkCod(df_exe_performance_single_intel)
#Showing result example
df_exe_performance_single_intel.head()
The following code shows the power consumption of single executions, for both host.
#bla = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='c1']
#display( bla[bla['cod_x']=='c1l25'] )
pd.set_option('precision', 1)
df_exe_energy_single_amd_c1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_amd_m2_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='m2']\
.groupby('UL').mean().reset_index()
df_exe_energy_single_amd_f1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='f1']\
.groupby('UL').mean().reset_index()
df_exe_energy_single_intel_c1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_intel_m2_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='m2']\
.groupby('UL').mean().reset_index()
df_exe_energy_single_intel_f1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='f1']\
.groupby('UL').mean().reset_index()
df_result = pd.concat([
df_exe_energy_single_amd_c1_pw,\
df_exe_energy_single_amd_c1_pw['power_average']-AMD_IDLE_PC,\
df_exe_energy_single_amd_m2_pw['power_average'],\
df_exe_energy_single_amd_m2_pw['power_average']-AMD_IDLE_PC,\
df_exe_energy_single_amd_f1_pw['power_average'],\
df_exe_energy_single_amd_f1_pw['power_average']-AMD_IDLE_PC,\
df_exe_energy_single_intel_c1_pw['power_average'],\
df_exe_energy_single_intel_c1_pw['power_average']-INTEL_IDLE_PC,\
df_exe_energy_single_intel_m2_pw['power_average'],\
df_exe_energy_single_intel_m2_pw['power_average']-INTEL_IDLE_PC,\
df_exe_energy_single_intel_f1_pw['power_average'],\
df_exe_energy_single_intel_f1_pw['power_average']-INTEL_IDLE_PC\
],\
axis=1)
df_result.columns = ['UL',
'AMD cpu',
'AMD cpu EC',
'AMD memory',
'AMD memory EC',
'AMD disk',
'AMD disk EC' ,
'Intel cpu',
'Intel cpu EC',
'Intel memory',
'Intel memory EC',
'Intel disk',
'Intel disk EC'
]
display (df_result,'Energy-simple-AMD')
aux = df_result.plot(x='UL', y=['AMD cpu', 'AMD memory','AMD disk', 'Intel cpu', 'Intel memory','Intel disk'],\
figsize=(10, 8)
)
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Power (W)")
The following code shows the power consumption of combined executions (in pairs) for both host.
df_exe_energy_double_amd_pw_c1m2 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='c1m2']\
.groupby(['ULx','ULy']).mean().reset_index()
df_exe_energy_double_amd_pw_c1f1 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='c1f1']\
.groupby(['ULx','ULy']).mean().reset_index()
df_exe_energy_double_amd_pw_m2f1 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='m2f1']\
.groupby(['ULx','ULy']).mean().reset_index()
df_exe_energy_double_intel_pw_c1m2 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1m2']\
.groupby(['ULx','ULy']).mean().reset_index()
df_exe_energy_double_intel_pw_c1f1 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1f1']\
.groupby(['ULx','ULy']).mean().reset_index()
df_exe_energy_double_intel_pw_m2f1 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='m2f1']\
.groupby(['ULx','ULy']).mean().reset_index()
df_result = pd.concat([\
df_exe_energy_double_amd_pw_c1m2,\
df_exe_energy_double_amd_pw_c1m2['power_average']-AMD_IDLE_PC,\
df_exe_energy_double_amd_pw_c1f1['power_average'],\
df_exe_energy_double_amd_pw_c1f1['power_average']-AMD_IDLE_PC,\
df_exe_energy_double_amd_pw_m2f1['power_average'],\
df_exe_energy_double_amd_pw_m2f1['power_average']-AMD_IDLE_PC,\
df_exe_energy_double_intel_pw_c1m2['power_average'],\
df_exe_energy_double_intel_pw_c1m2['power_average']-INTEL_IDLE_PC,\
df_exe_energy_double_intel_pw_c1f1['power_average'],\
df_exe_energy_double_intel_pw_c1f1['power_average']-INTEL_IDLE_PC,\
df_exe_energy_double_intel_pw_m2f1['power_average'],\
df_exe_energy_double_intel_pw_m2f1['power_average']-INTEL_IDLE_PC\
],axis=1)
df_result.columns = ['ULx',
'ULy',
'AMD cpu mem',
'AMD cpu mem EC',
'AMD cpu disk',
'AMD cpu disk EC',
'AMD mem disk',
'AMD mem disk EC',
'Intel cpu mem',
'Intel cpu mem EC',
'Intel cpu disk',
'Intel cpu disk EC',
'Intel mem disk',
'Intel mem disk EC']
display (df_result,'Energy-double')
aux = df_result.plot(x= ['ULx','ULy'],y=['AMD cpu mem', 'AMD cpu disk', 'AMD mem disk',\
'Intel cpu mem', 'Intel cpu disk', 'Intel mem disk'],kind='bar', figsize=(10, 8))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Power (W)")
The following code shows the power consumption of combined executions (in three) for both host.
df_exe_energy_triple_amd_pw_c1m2f1 = df_exe_energy_triple_amd[df_exe_energy_triple_amd['bkcod']=='c1m2f1']\
.groupby(['ULx','ULy','ULz']).mean().reset_index()
df_exe_energy_triple_intel_pw_c1m2f1 = df_exe_energy_triple_intel[df_exe_energy_triple_intel['bkcod']=='c1m2f1']\
.groupby(['ULx','ULy','ULz']).mean().reset_index()
df_result = pd.concat([\
df_exe_energy_triple_amd_pw_c1m2f1,
df_exe_energy_triple_amd_pw_c1m2f1['power_average']-AMD_IDLE_PC,
df_exe_energy_triple_intel_pw_c1m2f1['power_average'],\
df_exe_energy_triple_intel_pw_c1m2f1['power_average']-INTEL_IDLE_PC\
],axis=1)
df_result.columns = ['ULx', 'ULy', 'ULz',
'AMD cpu mem disk',
'AMD cpu mem disk EC',
'Intel cpu mem disk',
'Intel cpu mem disk EC'
]
display(df_result,'Energy-CPU-Memory-Disk-triple')
aux= df_result.plot(x= ['ULx','ULy','ULz'],y=['AMD cpu mem disk', 'Intel cpu mem disk'],kind='bar', figsize=(8, 5))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Power (W)")
df_exe_energy_triple_amd_pw_c1m2f1 = df_exe_energy_triple_amd[df_exe_energy_triple_amd['bkcod']=='c1m2f1']\
.groupby(['ULx','ULy','ULz']).std().reset_index()
df_exe_energy_triple_intel_pw_c1m2f1 = df_exe_energy_triple_intel[df_exe_energy_triple_intel['bkcod']=='c1m2f1']\
.groupby(['ULx','ULy','ULz']).std().reset_index()
df_result = pd.concat([\
df_exe_energy_triple_amd_pw_c1m2f1,\
df_exe_energy_triple_intel_pw_c1m2f1['power_average'],\
],axis=1)
df_result.columns = ['ULx', 'ULy', 'ULz', 'AMD cpu mem disk', 'Intel cpu mem disk']
display(df_result,'Energy-CPU-Memory-Disk-triple')
aux= df_result.plot(x= ['ULx','ULy','ULz'],y=['AMD cpu mem disk', 'Intel cpu mem disk'],kind='bar', figsize=(8, 5))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Power (W)")
The following code shows the peformance of single executions for both host.
display(df_exe_performance_single_amd[df_exe_performance_single_amd['exe']=='20170207194619767'])
pd.set_option('precision', 1)
df_exe_performance_single_amd_pw_c1unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='c1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_exe_performance_single_amd_pw_m2unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='m2unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_exe_performance_single_amd_pw_f1unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='f1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_exe_performance_single_intel_pw_c1unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='c1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_exe_performance_single_intel_pw_m2unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='m2unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_exe_performance_single_intel_pw_f1unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='f1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).mean().reset_index()
df_result = pd.concat([df_exe_performance_single_amd_pw_c1unt,\
df_exe_performance_single_amd_pw_m2unt['seconds'],\
df_exe_performance_single_amd_pw_f1unt['seconds'],\
df_exe_performance_single_intel_pw_c1unt['seconds'],\
df_exe_performance_single_intel_pw_m2unt['seconds'],\
df_exe_performance_single_intel_pw_f1unt['seconds']],\
axis=1)
df_result.columns = ['UL', 'AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu', 'Intel mem', 'Intel disk']
display (df_result,'Performance-single')
aux=df_result.plot(x= ['UL'],y=['AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu',\
'Intel mem', 'Intel disk'])
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Makespan (s)")
Efficiency metric is defined as $PC \times \;makespan \;/ \;3600 \;/\; number \;of\; instances$, where $PC$ is the Overall Power Consumption. The following code shows the metric for all benchmarks in both host. The more efficient level of utilization for each benchmark is highlighted.
pd.set_option('precision', 3)
df_result = pd.concat([df_exe_energy_single_amd_c1_pw['UL'],\
df_exe_energy_single_amd_c1_pw['power_average']*\
df_exe_performance_single_amd_pw_c1unt['seconds']/\
(df_exe_energy_single_amd_c1_pw['UL']*3/12.5)/3600,\
df_exe_energy_single_amd_m2_pw['power_average']*\
df_exe_performance_single_amd_pw_m2unt['seconds']/\
(df_exe_energy_single_amd_m2_pw['UL']*3/12.5)/3600,\
df_exe_energy_single_amd_f1_pw['power_average']*\
df_exe_performance_single_amd_pw_f1unt['seconds']/\
(df_exe_energy_single_amd_f1_pw['UL']*3/12.5)/3600,\
df_exe_energy_single_intel_c1_pw['power_average']*\
df_exe_performance_single_intel_pw_c1unt['seconds']/\
(df_exe_energy_single_intel_c1_pw['UL']*3/12.5)/3600,\
df_exe_energy_single_intel_m2_pw['power_average']*\
df_exe_performance_single_intel_pw_m2unt['seconds']/\
(df_exe_energy_single_intel_m2_pw['UL']*3/12.5)/3600,\
df_exe_energy_single_intel_f1_pw['power_average']*\
df_exe_performance_single_intel_pw_f1unt['seconds']/\
(df_exe_energy_single_intel_f1_pw['UL']*3/12.5)/3600,\
],
axis=1)
df_result.columns = ['UL', 'AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu', 'Intel mem', 'Intel disk']
def highlight_min(s):
is_min = s == s.min()
return ['background-color: yellow' if v else '' for v in is_min]
df_result.style.apply(highlight_min, subset=['AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu', 'Intel mem', 'Intel disk'])
The following code compares the effective power consumption of executions in sigle or double modality. The following figure ilustrates the concept. Different color indicates different benchmarks.
The bar graphic below shows the power gain (or loss) of executions combined over executions independently. In this case the idle consumption is not considered.
# CPU MEM AMD
df_left = df_exe_energy_double_amd_pw_c1m2
df_right = df_exe_energy_single_amd_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_amd_m2_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'AMD cpu + mem PC', 'AMD cpu PC','AMD mem PC']
df_result_AMD_CPUMEM = pd.concat([\
df_result,\
(df_result['AMD cpu + mem PC'] - AMD_IDLE_PC-\
(df_result['AMD cpu PC'] + df_result['AMD mem PC'] - AMD_IDLE_PC - AMD_IDLE_PC))*-1,\
],axis=1)
df_result_AMD_CPUMEM.columns = ['ULx','ULy', 'AMD cpu + mem PC', 'AMD cpu PC','AMD mem PC',\
'AMD cpu-mem EC']
df_result_AMD_CPUMEM = df_result_AMD_CPUMEM[['ULx','ULy', 'AMD cpu-mem EC']]
# CPU DISK AMD
df_left = df_exe_energy_double_amd_pw_c1f1
df_right = df_exe_energy_single_amd_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_amd_f1_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'AMD cpu + disk PC', 'AMD cpu PC','AMD disk PC']
df_result_AMD_CPUDISK = pd.concat([\
df_result,\
(df_result['AMD cpu + disk PC'] - AMD_IDLE_PC-\
(df_result['AMD cpu PC'] + df_result['AMD disk PC'] - AMD_IDLE_PC - AMD_IDLE_PC))*-1,\
],axis=1)
df_result_AMD_CPUDISK.columns = ['ULx','ULy', 'AMD cpu + disk PC', 'AMD cpu PC','AMD disk PC',\
'AMD cpu-disk EC']
df_result_AMD_CPUDISK = df_result_AMD_CPUDISK[['ULx','ULy', 'AMD cpu-disk EC']]
# MEM DISK AMD
df_left = df_exe_energy_double_amd_pw_m2f1
df_right = df_exe_energy_single_amd_m2_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_amd_f1_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'AMD mem + disk PC', 'AMD mem PC','AMD disk PC']
df_result_AMD_MEMDISK = pd.concat([\
df_result,\
(df_result['AMD mem + disk PC'] - AMD_IDLE_PC-\
(df_result['AMD mem PC'] + df_result['AMD disk PC'] - AMD_IDLE_PC - AMD_IDLE_PC))*-1,\
],axis=1)
df_result_AMD_MEMDISK.columns = ['ULx','ULy', 'AMD mem + disk PC', 'AMD mem PC','AMD disk PC',\
'AMD mem-disk EC']
df_result_AMD_MEMDISK = df_result_AMD_MEMDISK[['ULx','ULy', 'AMD mem-disk EC']]
# CPU MEM INTEL
df_left = df_exe_energy_double_intel_pw_c1m2
df_right = df_exe_energy_single_intel_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_intel_m2_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'INTEL cpu + mem PC', 'INTEL cpu PC','INTEL mem PC']
df_result_INTEL_CPUMEM = pd.concat([\
df_result,\
(df_result['INTEL cpu + mem PC'] - INTEL_IDLE_PC-\
(df_result['INTEL cpu PC'] + df_result['INTEL mem PC'] - INTEL_IDLE_PC - INTEL_IDLE_PC))*-1,\
],axis=1)
df_result_INTEL_CPUMEM.columns = ['ULx','ULy', 'INTEL cpu + mem PC', 'INTEL cpu PC','INTEL mem PC',\
'INTEL cpu-mem EC']
df_result_INTEL_CPUMEM = df_result_INTEL_CPUMEM[['ULx','ULy', 'INTEL cpu-mem EC']]
# CPU DISK INTEL
df_left = df_exe_energy_double_intel_pw_c1f1
df_right = df_exe_energy_single_intel_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_intel_f1_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'INTEL cpu + disk PC', 'INTEL cpu PC','INTEL disk PC']
df_result_INTEL_CPUDISK = pd.concat([\
df_result,\
(df_result['INTEL cpu + disk PC'] - INTEL_IDLE_PC-\
(df_result['INTEL cpu PC'] + df_result['INTEL disk PC'] - INTEL_IDLE_PC - INTEL_IDLE_PC))*-1,\
],axis=1)
df_result_INTEL_CPUDISK.columns = ['ULx','ULy', 'INTEL cpu + disk PC', 'INTEL cpu PC','INTEL disk PC',\
'INTEL cpu-disk EC']
df_result_INTEL_CPUDISK = df_result_INTEL_CPUDISK[['ULx','ULy', 'INTEL cpu-disk EC']]
# MEM DISK INTEL
df_left = df_exe_energy_double_intel_pw_m2f1
df_right = df_exe_energy_single_intel_m2_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_right = df_exe_energy_single_intel_f1_pw
df_result = pd.merge(df_result, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_result = df_result[['ULx','ULy', 'power_average_x', 'power_average_y', 'power_average']]
df_result.columns = ['ULx','ULy', 'INTEL mem + disk PC', 'INTEL mem PC','INTEL disk PC']
df_result_INTEL_MEMDISK = pd.concat([\
df_result,\
(df_result['INTEL mem + disk PC'] - INTEL_IDLE_PC-\
(df_result['INTEL mem PC'] + df_result['INTEL disk PC'] - INTEL_IDLE_PC - INTEL_IDLE_PC))*-1,\
],axis=1)
df_result_INTEL_MEMDISK.columns = ['ULx','ULy', 'INTEL mem + disk PC', 'INTEL mem PC','INTEL disk PC',\
'INTEL mem-disk EC']
df_result_INTEL_MEMDISK = df_result_INTEL_MEMDISK[['ULx','ULy', 'INTEL mem-disk EC']]
#print all together
df_result = pd.concat([\
df_result_AMD_CPUMEM,\
df_result_AMD_CPUDISK['AMD cpu-disk EC'],\
df_result_AMD_MEMDISK['AMD mem-disk EC'],\
df_result_INTEL_CPUMEM['INTEL cpu-mem EC'],\
df_result_INTEL_CPUDISK['INTEL cpu-disk EC'],\
df_result_INTEL_MEMDISK['INTEL mem-disk EC'],\
],axis=1)
display(df_result,'Energy double VS single energy gain')
aux= df_result.plot(x= ['ULx','ULy'],y=['AMD cpu-mem EC',\
'AMD cpu-disk EC',\
'AMD mem-disk EC',\
'INTEL cpu-mem EC',\
'INTEL cpu-disk EC',\
'INTEL mem-disk EC',\
],kind='bar',figsize=(10, 8))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Effective Power gain (or loss) by executing in doble (W)")
The following code compares the effective power consumption of executes in sigle or triple modality.
#AMD
df_left = df_exe_energy_triple_amd_pw_c1m2f1
df_right = df_exe_energy_single_amd_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_left = df_result
df_right = df_exe_energy_single_amd_m2_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_left = df_result
df_right = df_exe_energy_single_amd_f1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULz'],right_on= ['UL'])
df_result.columns = ['ULx','ULy','ULz', 'AMD cpu + mem + disk PC','foo1', 'AMD cpu PC','foo2',\
'AMD mem PC','foo3','AMD disk PC']
df_result = df_result[['ULx','ULy','ULz', 'AMD cpu + mem + disk PC', 'AMD cpu PC',\
'AMD mem PC','AMD disk PC']]
df_result_AMD_CPUMEMDISK = pd.concat([\
df_result,\
(df_result['AMD cpu + mem + disk PC'] - AMD_IDLE_PC-\
(df_result['AMD cpu PC'] + df_result['AMD mem PC'] + df_result['AMD disk PC'] \
- AMD_IDLE_PC * 3))*-1,\
],axis=1)
df_result_AMD_CPUMEMDISK.columns = ['ULx','ULy','ULz', 'AMD cpu + mem + disk PC', 'AMD cpu PC',\
'AMD mem PC','AMD disk PC','AMD cpu + mem + disk EC']
#INTEL
df_left = df_exe_energy_triple_intel_pw_c1m2f1
df_right = df_exe_energy_single_intel_c1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULx'],right_on= ['UL'])
df_left = df_result
df_right = df_exe_energy_single_intel_m2_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULy'],right_on= ['UL'])
df_left = df_result
df_right = df_exe_energy_single_intel_f1_pw
df_result = pd.merge(df_left, df_right, how='left', left_on=['ULz'],right_on= ['UL'])
df_result.columns = ['ULx','ULy','ULz', 'INTEL cpu + mem + disk PC','foo1', 'INTEL cpu PC','foo2',\
'INTEL mem PC','foo3','INTEL disk PC']
df_result = df_result[['ULx','ULy','ULz', 'INTEL cpu + mem + disk PC', 'INTEL cpu PC',\
'INTEL mem PC','INTEL disk PC']]
df_result_INTEL_CPUMEMDISK = pd.concat([\
df_result,\
(df_result['INTEL cpu + mem + disk PC'] - INTEL_IDLE_PC-\
(df_result['INTEL cpu PC'] + df_result['INTEL mem PC'] + df_result['INTEL disk PC'] \
- INTEL_IDLE_PC * 3))*-1,\
],axis=1)
df_result_INTEL_CPUMEMDISK.columns = ['ULx','ULy','ULz', 'INTEL cpu + mem + disk PC', 'INTEL cpu PC',\
'INTEL mem PC','INTEL disk PC','INTEL cpu + mem + disk EC']
#print all together
df_result = pd.concat([\
df_result_AMD_CPUMEMDISK,\
df_result_INTEL_CPUMEMDISK\
[['INTEL cpu + mem + disk PC', 'INTEL cpu PC',\
'INTEL mem PC','INTEL disk PC','INTEL cpu + mem + disk EC']]\
],axis=1)
display(df_result,'Energy double VS single energy gain')
aux=df_result.plot(x= ['ULx','ULy','ULz'],y=['AMD cpu + mem + disk EC',\
'INTEL cpu + mem + disk EC',
],kind='bar',figsize=(8, 7))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Effective Power gain (or loss) by executing in triple (W)")
In this section the previous data is utilized to find dependencies between the variables of the problem:
The first and simplest model considers only the dependency between utilization level and power consumption. In this model all the workload is considered CPU-bound. The following ecuation shows the relation, where $\alpha$ is the utilization level and $e$ is the power consumption predicted.
\begin{equation} f(\alpha) \to e,\; \alpha \in [0,100] \wedge e \in \rm I\!R \end{equation}The experimental data considered to this model is the CPU-bound benchmark execution on AMD an Intel host.
df_exe_energy_single_amd_c1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_intel_c1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
display(pd.concat([df_exe_energy_single_amd_c1_pw,df_exe_energy_single_intel_c1_pw],axis=1))
Model 1 can be resolved by linear regretion. The following code resolves the problem and shows the parameter founded. The model can be adjunted....
# create linear model
linear_model_amd = smf.ols(formula='power_average ~ UL', data=df_exe_energy_single_amd_c1_pw).fit()
linear_model_intel = smf.ols(formula='power_average ~ UL', data=df_exe_energy_single_intel_c1_pw).fit()
# Showing coef
print(linear_model_amd.params)
print(linear_model_intel.params)
X_theoretical = pd.DataFrame({'UL': [0, 100]})
predict_amd = linear_model_amd.predict(X_theoretical)
predict_intel = linear_model_intel.predict(X_theoretical)
f, (ax1, ax2) = plt.subplots(1, 2, sharey=False, figsize=(14, 8))
ax1.plot(X_theoretical, predict_amd)
df_exe_energy_single_amd_c1_pw.plot(kind='scatter', x='UL', y='power_average', ax=ax1)
ax1.set_title('AMD linear model')
ax2.plot(X_theoretical, predict_intel)
df_exe_energy_single_intel_c1_pw.plot(kind='scatter', x='UL', y='power_average', ax=ax2)
ax2.set_title('Intel linear model')
Python provides test over the models
print (linear_model_amd.summary())
print (linear_model_intel.summary())
The second model considers the dependency between type of computational resuorce, utilization level and power consumption. However, the intelationship in the combined execution is not considered. The following ecuation shows the relation, where $\alpha$ is the utilization level of CPU, $\beta$ is the utilization level of memory, $\gamma$ is the utilization level of disk and $e$ is the power consumption predicted.
\begin{equation} f(\alpha,\beta,\gamma) \to e,\; \alpha \in [0,100] \wedge e \in \rm I\!R \end{equation}The experimental data considered to this model is the single CPU-bound, Memory-bound and Disk-bound benchmark executions, on AMD an Intel host.
df_exe_energy_single_amd_c1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_intel_c1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='c1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_amd_m2_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='m2']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_intel_m2_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='m2']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_amd_f1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='f1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_intel_f1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='f1']\
.groupby(['UL']).mean().reset_index()
df_exe_energy_single_amd_pw = pd.concat(\
[df_exe_energy_single_amd_c1_pw,\
df_exe_energy_single_amd_m2_pw,\
df_exe_energy_single_amd_f1_pw]\
,axis=1)
df_exe_energy_single_amd_pw.columns = ['ul_cpu','power_cpu','ul_mem', 'power_mem','ul_disk','power_disk']
df_exe_energy_single_intel_pw = pd.concat(\
[df_exe_energy_single_intel_c1_pw,\
df_exe_energy_single_intel_m2_pw,\
df_exe_energy_single_intel_f1_pw]\
,axis=1)
df_exe_energy_single_intel_pw.columns = ['ul_cpu','power_cpu','ul_mem', 'power_mem','ul_disk','power_disk']
# IDLE substraction
df_exe_energy_single_amd_pw.power_cpu = df_exe_energy_single_amd_pw.power_cpu - AMD_IDLE_PC
df_exe_energy_single_amd_pw.power_mem = df_exe_energy_single_amd_pw.power_mem - AMD_IDLE_PC
df_exe_energy_single_amd_pw.power_disk = df_exe_energy_single_amd_pw.power_disk - AMD_IDLE_PC
df_exe_energy_single_amd_pw['power'] = df_exe_energy_single_amd_pw.power_cpu+\
df_exe_energy_single_amd_pw.power_mem+\
df_exe_energy_single_amd_pw.power_disk
df_exe_energy_single_intel_pw.power_cpu = df_exe_energy_single_intel_pw.power_cpu - INTEL_IDLE_PC
df_exe_energy_single_intel_pw.power_mem = df_exe_energy_single_intel_pw.power_mem - INTEL_IDLE_PC
df_exe_energy_single_intel_pw.power_disk = df_exe_energy_single_intel_pw.power_disk - INTEL_IDLE_PC
df_exe_energy_single_intel_pw['power'] = df_exe_energy_single_intel_pw.power_cpu+\
df_exe_energy_single_intel_pw.power_mem+\
df_exe_energy_single_intel_pw.power_disk
#display(df_exe_energy_single_amd_pw)
We consider three linear models independly
# create linear model
linear_model_amd_cpu = smf.ols(formula='power_cpu ~ ul_cpu', \
data=df_exe_energy_single_amd_pw).fit()
linear_model_amd_mem = smf.ols(formula='power_mem ~ ul_mem', \
data=df_exe_energy_single_amd_pw).fit()
linear_model_amd_disk = smf.ols(formula='power_disk ~ ul_disk', \
data=df_exe_energy_single_amd_pw).fit()
# create linear model
linear_model_intel_cpu = smf.ols(formula='power_cpu ~ ul_cpu', \
data=df_exe_energy_single_intel_pw).fit()
linear_model_intel_mem = smf.ols(formula='power_mem ~ ul_mem', \
data=df_exe_energy_single_intel_pw).fit()
linear_model_intel_disk = smf.ols(formula='power_disk ~ ul_disk', \
data=df_exe_energy_single_intel_pw).fit()
#print(linear_model_intel_cpu.params)
#print(linear_model_intel_mem.params)
#print(linear_model_amd_cpu.params)
#print(linear_model_amd_mem.params)
#print(linear_model_amd_mem.summary())
#print(linear_model_intel_mem.params)
#print(linear_model_amd_cpu.params)
#print(linear_model_amd_mem.params)
# Showing coef
#print(linear_model_amd_cpu.params)
#print(linear_model_amd_mem.params)
#print(linear_model_amd_disk.params)
X_theoretical = pd.DataFrame({'ul_cpu': [0, 100],'ul_mem': [0, 100],'ul_disk': [0, 100]})
predict_amd_cpu = linear_model_amd_cpu.predict(X_theoretical)
predict_amd_mem = linear_model_amd_mem.predict(X_theoretical)
predict_amd_disk = linear_model_amd_disk.predict(X_theoretical)
predict_intel_cpu = linear_model_intel_cpu.predict(X_theoretical)
predict_intel_mem = linear_model_intel_mem.predict(X_theoretical)
predict_intel_disk = linear_model_intel_disk.predict(X_theoretical)
f, ((ax1, ax2,ax3),(ax4,ax5,ax6)) = plt.subplots(2, 3, sharey=False, figsize=(12, 10))
ax1.plot(X_theoretical, predict_amd_cpu)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu', ax=ax1)
ax1.set_title('CPU linear model. AMD host')
ax2.plot(X_theoretical, predict_amd_mem)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax2)
ax2.set_title('Memory linear model. AMD host')
ax3.plot(X_theoretical, predict_amd_disk)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_disk', y='power_disk', ax=ax3)
ax3.set_title('Disk linear model. AMD host')
ax1.set_xlabel("Utilization level (%)")
ax1.set_ylabel("Power Consumption (W)")
ax2.set_xlabel("Utilization level (%)")
ax2.set_ylabel("Power Consumption (W)")
ax3.set_xlabel("Utilization level (%)")
ax3.set_ylabel("Power Consumption (W)")
ax4.plot(X_theoretical, predict_intel_cpu)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu', ax=ax4)
ax4.set_title('CPU linear model. Intel host')
ax5.plot(X_theoretical, predict_intel_mem)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax5)
ax5.set_title('Memory linear model. intel host')
ax6.plot(X_theoretical, predict_intel_disk)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_disk', y='power_disk', ax=ax6)
ax6.set_title('Disk linear model. Intel host')
ax4.set_xlabel("Utilization level (%)")
ax4.set_ylabel("Power Consumption (W)")
ax5.set_xlabel("Utilization level (%)")
ax5.set_ylabel("Power Consumption (W)")
ax6.set_xlabel("Utilization level (%)")
ax6.set_ylabel("Power Consumption (W)")
Next the R-suared metric of the models is showed.
print("CPU model. AMD. R-squared: ",linear_model_amd_cpu.rsquared)
print("Memory model. AMD. R-squared: ",linear_model_amd_mem.rsquared)
print("Disk model. AMD. R-squared: ",linear_model_amd_disk.rsquared)
print("CPU model. Intel. R-squared: ",linear_model_amd_cpu.rsquared)
print("Memory model R-squared: ",linear_model_amd_mem.rsquared)
print("Disk model R-squared: ",linear_model_amd_disk.rsquared)
It is posible adjust the cpu model for impoving the R-squared metric. Quadratic and piecewise function is presented below.
linear_model_amd_cpu_2 = smf.ols(formula='power_cpu ~ ul_cpu + np.power(ul_cpu,2)', \
data=df_exe_energy_single_amd_pw).fit()
predict_amd_cpu_2 = linear_model_amd_cpu_2.predict(X_theoretical)
linear_model_intel_cpu_2 = smf.ols(formula='power_cpu ~ ul_cpu + np.power(ul_cpu,2)', \
data=df_exe_energy_single_intel_pw).fit()
predict_intel_cpu_2 = linear_model_intel_cpu_2.predict(X_theoretical)
f, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2, 2, sharey=False, figsize=(12, 10))
ax1.plot(X_theoretical, predict_amd_cpu_2)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu', ax=ax1)
ax1.set_title('CPU quadratic model. AMD host')
ax3.plot(X_theoretical, predict_intel_cpu_2)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu', ax=ax3)
ax3.set_title('CPU quadratic model. Intel host')
print(linear_model_amd_cpu_2.params)
print(linear_model_amd_cpu_2.rsquared)
print(linear_model_intel_cpu_2.params)
print(linear_model_intel_cpu_2.rsquared)
#AMD
# piecewise linear data prepare
ul_cpu2 = np.where(df_exe_energy_single_amd_pw['ul_cpu'] > 50, df_exe_energy_single_amd_pw['ul_cpu'] - 50, 0)
df_exe_energy_single_amd_pw['ul_cpu2'] = ul_cpu2
#print(df_exe_energy_single_amd_pw)
# piecewise linear regression
linear_model_amd_cpu_3 = smf.ols(formula = 'power_cpu ~ ul_cpu + ul_cpu2', data = df_exe_energy_single_amd_pw).fit()
predict_amd_cpu_3 = linear_model_amd_cpu_3.predict()
ax2.plot(df_exe_energy_single_amd_pw.ul_cpu,predict_amd_cpu_3)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu',ax=ax2)
ax2.set_title('CPU linear piecewise model. AMD host')
#INTEL
# piecewise linear data prepare
ul_cpu2 = np.where(df_exe_energy_single_amd_pw['ul_cpu'] > 50, df_exe_energy_single_amd_pw['ul_cpu'] - 50, 0)
df_exe_energy_single_intel_pw['ul_cpu2'] = ul_cpu2
#print(df_exe_energy_single_amd_pw)
# piecewise linear regression
linear_model_intel_cpu_3 = smf.ols(formula = 'power_cpu ~ ul_cpu + ul_cpu2', data = df_exe_energy_single_intel_pw).fit()
predict_intel_cpu_3 = linear_model_intel_cpu_3.predict()
ax4.plot(df_exe_energy_single_intel_pw.ul_cpu,predict_intel_cpu_3)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_cpu', y='power_cpu',ax=ax4)
ax4.set_title('CPU linear piecewise model. Intel host')
#Sowing two examples of piecewise model usage
x_test1 = 22
x_test2 = 77
# auxiliar function
H = lambda h: h-50 if h>50 else 0
y_test1,y_test2=linear_model_intel_cpu_3.predict(pd.DataFrame({'ul_cpu': [x_test1,x_test2],\
'ul_cpu2': [H(x_test1),H(x_test2)]}))
plt.plot([x_test1], [y_test1], marker='o', markersize=10, color="red")
plt.plot([x_test2], [y_test2], marker='o', markersize=10, color="red")
#print("y_test2="+str(y_test2))
#ax1.set_xlabel("Utilization level (%)")
#ax1.set_ylabel("Power Consumption (W)")
#ax2.set_xlabel("Utilization level (%)")
#ax2.set_ylabel("Power Consumption (W)")
#print(linear_model_amd_cpu_3.params)
#print(linear_model_intel_cpu_3.rsquared)
#print(linear_model_intel_cpu_3.params)
#print(linear_model_intel_cpu_3.rsquared)
It is posible adjust the memory model for impoving the R-squared metric. Quadratic and piecewise function is presented below.
linear_model_amd_mem_2 = smf.ols(formula='power_mem ~ ul_mem + np.power(ul_mem,2)', \
data=df_exe_energy_single_amd_pw).fit()
predict_amd_mem_2 = linear_model_amd_mem_2.predict(X_theoretical)
linear_model_intel_mem_2 = smf.ols(formula='power_mem ~ ul_mem + np.power(ul_mem,2)', \
data=df_exe_energy_single_intel_pw).fit()
predict_intel_mem_2 = linear_model_intel_mem_2.predict(X_theoretical)
#X_theoretical = pd.DataFrame({'ul_cpu': [0, 100],'ul_mem': [0, 100],'ul_disk': [0, 100]})
f, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2, 2, sharey=False, figsize=(12, 10))
ax1.plot(X_theoretical, predict_amd_mem_2)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax1)
ax1.set_title('Memory quadratic model. AMD host')
ax3.plot(X_theoretical, predict_intel_mem_2)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax3)
ax3.set_title('Memory quadratic model. Intel host')
print(linear_model_amd_mem_2.params)
print(linear_model_amd_mem_2.rsquared)
print(linear_model_intel_mem_2.params)
print(linear_model_intel_mem_2.rsquared)
#AMD
# piecewise linear data prepare
ul_mem2 = np.where(df_exe_energy_single_amd_pw['ul_mem'] > 50, df_exe_energy_single_amd_pw['ul_mem'] - 50, 0)
df_exe_energy_single_amd_pw['ul_mem2'] = ul_mem2
#print(df_exe_energy_single_amd_pw)
# piecewise linear regression
linear_model_amd_mem_3 = smf.ols(formula = 'power_mem ~ ul_mem + ul_mem2', data = df_exe_energy_single_amd_pw).fit()
predict_amd_mem_3 = linear_model_amd_mem_3.predict()
ax2.plot(df_exe_energy_single_amd_pw.ul_mem,predict_amd_mem_3)
df_exe_energy_single_amd_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax2)
ax2.set_title('Memory linear piecewise model. AMD host')
#Sowing two examples of piecewise model usage
x_test1 = 22
x_test2 = 77
# auxiliar function
H = lambda h: h-50 if h>50 else 0
y_test1,y_test2=linear_model_amd_mem_3.predict(pd.DataFrame({'ul_mem': [x_test1,x_test2],\
'ul_mem2': [H(x_test1),H(x_test2)]}))
#plt.plot([x_test1], [y_test1], marker='o', markersize=10, color="red")
#plt.plot([x_test2], [y_test2], marker='o', markersize=10, color="red")
print("y_test2="+str(y_test2))
#INTEL
# piecewise linear data prepare
ul_mem2 = np.where(df_exe_energy_single_amd_pw['ul_mem'] > 50, df_exe_energy_single_amd_pw['ul_mem'] - 50, 0)
df_exe_energy_single_intel_pw['ul_mem2'] = ul_mem2
#print(df_exe_energy_single_amd_pw)
# piecewise linear regression
linear_model_intel_mem_3 = smf.ols(formula = 'power_mem ~ ul_mem + ul_mem2', data = df_exe_energy_single_intel_pw).fit()
predict_intel_mem_3 = linear_model_intel_mem_3.predict()
ax4.plot(df_exe_energy_single_intel_pw.ul_mem,predict_intel_mem_3)
df_exe_energy_single_intel_pw.plot(kind='scatter', x='ul_mem', y='power_mem', ax=ax4)
ax4.set_title('Memory linear piecewise model. Intel host')
#Sowing two examples of piecewise model usage
x_test1 = 22
x_test2 = 77
# auxiliar function
H = lambda h: h-50 if h>50 else 0
y_test1,y_test2=linear_model_intel_mem_3.predict(pd.DataFrame({'ul_mem': [x_test1,x_test2],\
'ul_mem2': [H(x_test1),H(x_test2)]}))
#plt.plot([x_test1], [y_test1], marker='o', markersize=10, color="red")
#plt.plot([x_test2], [y_test2], marker='o', markersize=10, color="red")
#print("y_test2="+str(y_test2))
#Sowing two examples of piecewise model usage
#x_test1 = 22
#x_test2 = 77
# auxiliar function
#H = lambda h: h-50 if h>50 else 0
#y_test1,y_test2=linear_model_amd_mem_3.predict(pd.DataFrame({'ul_mem': [x_test1,x_test2],\
# 'ul_mem2': [H(x_test1),H(x_test2)]}))
#plt.plot([x_test1], [y_test1], marker='o', markersize=10, color="red")
#plt.plot([x_test2], [y_test2], marker='o', markersize=10, color="red")
#ax1.set_xlabel("Utilization level (%)")
#ax1.set_ylabel("Power Consumption (W)")
#ax2.set_xlabel("Utilization level (%)")
#ax2.set_ylabel("Power Consumption (W)")
#print(linear_model_intel_mem_3.params)
#print(linear_model_intel_mem_3.rsquared)
#print(linear_model_intel_mem_3.params)
#print(linear_model_intel_mem_3.rsquared)
#print(linear_model_amd_mem_3.summary())
And new R-squared values are
print("AMD. Linear model R-squared: ",linear_model_amd_cpu.rsquared)
print("INtel. Linear model R-squared: ",linear_model_intel_cpu.rsquared)
print("AMD. Linear model R-squared: ",linear_model_amd_mem.rsquared)
print("AMD. Quadratic model R-squared: ",linear_model_amd_mem_2.rsquared)
print("AMD.Piecewise model R-squared: ",linear_model_amd_mem_3.rsquared)
print("Intel. Linear model R-squared: ",linear_model_intel_mem.rsquared)
print("Intel. Quadratic model R-squared: ",linear_model_intel_mem_2.rsquared)
print("Intel. Piecewise model R-squared: ",linear_model_intel_mem_3.rsquared)
print("Intel. Quadratic model R-squared: ",linear_model_amd_mem_3.params)
print("Intel. Piecewise model R-squared: ",linear_model_intel_mem_3.params)
This model is lineal
X_theoretical = pd.DataFrame({'UL': [0, 100]})
df_exe_performance_single= pd.concat([df_exe_performance_single_amd_pw_c1unt,\
df_exe_performance_single_amd_pw_m2unt['seconds'],\
df_exe_performance_single_amd_pw_f1unt['seconds'],\
df_exe_performance_single_intel_pw_c1unt['seconds'],\
df_exe_performance_single_intel_pw_m2unt['seconds'],\
df_exe_performance_single_intel_pw_f1unt['seconds']],\
axis=1)
df_exe_performance_single.columns = ['UL', 'makespan_amd_cpu', 'makespan_amd_mem', 'makespan_amd_disk',\
'makespan_intel_cpu', 'makespan_intel_mem', 'makespan_intel_disk']
#AMD
linear_model_performance_amd_cpu = smf.ols(formula='makespan_amd_cpu ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_amd_cpu= linear_model_performance_amd_cpu.predict(X_theoretical)
linear_model_performance_amd_mem = smf.ols(formula='makespan_amd_mem ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_amd_mem= linear_model_performance_amd_mem.predict(X_theoretical)
linear_model_performance_amd_disk = smf.ols(formula='makespan_amd_disk ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_amd_disk= linear_model_performance_amd_disk.predict(X_theoretical)
#INTEL
linear_model_performance_intel_cpu = smf.ols(formula='makespan_intel_cpu ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_intel_cpu= linear_model_performance_intel_cpu.predict(X_theoretical)
linear_model_performance_intel_mem = smf.ols(formula='makespan_intel_mem ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_intel_mem= linear_model_performance_intel_mem.predict(X_theoretical)
linear_model_performance_intel_disk = smf.ols(formula='makespan_intel_disk ~ UL', \
data=df_exe_performance_single).fit()
predict_performance_intel_disk= linear_model_performance_intel_disk.predict(X_theoretical)
f, ((ax1, ax2,ax3),(ax4,ax5,ax6)) = plt.subplots(2, 3, sharey=False, figsize=(12, 10))
ax1.plot(X_theoretical, predict_performance_amd_cpu)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_amd_cpu', ax=ax1)
ax1.set_title('CPU linear model. AMD. Performance')
ax2.plot(X_theoretical, predict_performance_amd_mem)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_amd_mem', ax=ax2)
ax2.set_title('Memory linear model. AMD. Performance')
ax3.plot(X_theoretical, predict_performance_amd_disk)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_amd_disk', ax=ax3)
ax3.set_title('Disk linear model. AMD. Performance')
ax4.plot(X_theoretical, predict_performance_intel_cpu)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_intel_cpu', ax=ax4)
ax4.set_title('CPU linear model. Intel. Performance')
ax5.plot(X_theoretical, predict_performance_intel_mem)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_intel_mem', ax=ax5)
ax5.set_title('Memory linear model. Intel. Performance')
ax6.plot(X_theoretical, predict_performance_intel_disk)
df_exe_performance_single.plot(kind='scatter', x='UL', y='makespan_intel_disk', ax=ax6)
ax6.set_title('Disk linear model. Intel. Performance')
ax1.set_xlabel("Utilization level (%)")
ax1.set_ylabel("Makespan (s)")
ax2.set_xlabel("Utilization level (%)")
ax2.set_ylabel("Makespan (s)")
ax3.set_xlabel("Utilization level (%)")
ax3.set_ylabel("Makespan (s)")
ax4.set_xlabel("Utilization level (%)")
ax4.set_ylabel("Makespan (s)")
ax5.set_xlabel("Utilization level (%)")
ax5.set_ylabel("Makespan (s)")
ax6.set_xlabel("Utilization level (%)")
ax6.set_ylabel("Makespan (s)")
This notebook presented detailed python scripts for proccesing output files of power characterization experiments. It allows to expose the scientific method in a clear manner and minimize errors in calculations. Also, the processing is completely reproducible from raw data. The work shows different analysis of the data, comparing combined and single scenarios, taking advantage of pandas dataframe potential. Finally, different power consumption models are presented and implemented using linear regression. The python models are implemented easily and without errors. Several error tests over the models are provided by the framework. In the future more complex models (that consider the dependency of the combined execution) are going to be implemented.
Example of statistics test applied over AMD data, simple executions
def printStatisticTests(experiments):
shapiro_results = experiments.apply(lambda x:scipy.stats.shapiro(x),axis = 0)
ks_results = experiments.apply(lambda x:scipy.stats.kstest(x,cdf='norm'),axis = 0)
anderson_results = experiments.apply(lambda x:scipy.stats.anderson(x),axis = 0)
dagostino_results = experiments.apply(lambda x:scipy.stats.mstats.normaltest(x),axis = 0)
tests=pd.concat([shapiro_results,
ks_results,
anderson_results,
dagostino_results
]
,axis=1)
tests.columns = ['Shapiro-Wilk',
'Kolmogorov-Smirnov',
'Anderson-Darling',
'D’Agostino and Pearson',
]
display(tests)
#AMD CPU
experiments = pd.DataFrame()
experiments = pd.concat(
[
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l12y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l25']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l37y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l50']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l62y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l75']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l87y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l100']['power_average'].reset_index()
],axis=1)
experiments = experiments.drop(['index'], axis=1)
#display(experiments)
experiments.columns = ['c1l12y5',
'c1l25',
'c1l37y5',
'c1l50',
'c1l62y5',
'c1l75',
'c1l87y5',
'c1l100',
]
printStatisticTests(experiments)
#AMD MEM
experiments = pd.DataFrame()
experiments = pd.concat(
[
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l12y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l25']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l37y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l50']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l62y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l75']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l87y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='m2l100']['power_average'].reset_index()
],axis=1)
experiments = experiments.drop(['index'], axis=1)
#display(experiments)
experiments.columns = ['m2l12y5',
'm2l25',
'm2l37y5',
'm2l50',
'm2l62y5',
'm2l75',
'm2l87y5',
'm2l100',
]
printStatisticTests(experiments)
#AMD DISK
experiments = pd.DataFrame()
experiments = pd.concat(
[
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l12y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l25']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l37y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l50']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l62y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l75']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l87y5']['power_average'].reset_index(),
df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='f1l100']['power_average'].reset_index()
],axis=1)
experiments = experiments.drop(['index'], axis=1)
#display(experiments)
experiments.columns = ['f1l12y5',
'f1l25',
'f1l37y5',
'f1l50',
'f1l62y5',
'f1l75',
'f1l87y5',
'f1l100',
]
printStatisticTests(experiments)
df_exe_energy_single_amd_c1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='c1']\
.groupby(['UL']).std().reset_index()
df_exe_energy_single_amd_m2_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='m2']\
.groupby('UL').std().reset_index()
df_exe_energy_single_amd_f1_pw = df_exe_energy_single_amd[df_exe_energy_single_amd['bkcod']=='f1']\
.groupby('UL').std().reset_index()
df_exe_energy_single_intel_c1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='c1']\
.groupby(['UL']).std().reset_index()
df_exe_energy_single_intel_m2_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='m2']\
.groupby('UL').std().reset_index()
df_exe_energy_single_intel_f1_pw = df_exe_energy_single_intel[df_exe_energy_single_intel['bkcod']=='f1']\
.groupby('UL').std().reset_index()
df_result = pd.concat([df_exe_energy_single_amd_c1_pw,\
df_exe_energy_single_amd_m2_pw['power_average'],\
df_exe_energy_single_amd_f1_pw['power_average'],\
df_exe_energy_single_intel_c1_pw['power_average'],\
df_exe_energy_single_intel_m2_pw['power_average'],\
df_exe_energy_single_intel_f1_pw['power_average']],\
axis=1)
df_result.columns = ['UL', 'AMD cpu', 'AMD memory','AMD disk', 'Intel cpu', 'Intel memory','Intel disk']
display (df_result,'Energy-simple-AMD')
df_exe_energy_double_amd_pw_c1m2 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='c1m2']\
.groupby(['ULx','ULy']).std().reset_index()
df_exe_energy_double_amd_pw_c1f1 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='c1f1']\
.groupby(['ULx','ULy']).std().reset_index()
df_exe_energy_double_amd_pw_m2f1 = df_exe_energy_double_amd[df_exe_energy_double_amd['bkcod']=='m2f1']\
.groupby(['ULx','ULy']).std().reset_index()
df_exe_energy_double_intel_pw_c1m2 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1m2']\
.groupby(['ULx','ULy']).std().reset_index()
df_exe_energy_double_intel_pw_c1f1 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='c1f1']\
.groupby(['ULx','ULy']).std().reset_index()
df_exe_energy_double_intel_pw_m2f1 = df_exe_energy_double_intel[df_exe_energy_double_intel['bkcod']=='m2f1']\
.groupby(['ULx','ULy']).std().reset_index()
df_result = pd.concat([\
df_exe_energy_double_amd_pw_c1m2,\
df_exe_energy_double_amd_pw_c1f1['power_average'],\
df_exe_energy_double_amd_pw_m2f1['power_average'],\
df_exe_energy_double_intel_pw_c1m2['power_average'],\
df_exe_energy_double_intel_pw_c1f1['power_average'],\
df_exe_energy_double_intel_pw_m2f1['power_average'],\
],axis=1)
df_result.columns = ['ULx',
'ULy',
'AMD cpu mem',
'AMD cpu disk',
'AMD mem disk',
'Intel cpu mem',
'Intel cpu disk',
'Intel mem disk'
]
display (df_result,'Energy-double')
aux = df_result.plot(x= ['ULx','ULy'],y=['AMD cpu mem', 'AMD cpu disk', 'AMD mem disk',\
'Intel cpu mem', 'Intel cpu disk', 'Intel mem disk'],kind='bar', figsize=(10, 8))
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Power (W)")
df_exe_performance_single_amd_pw_c1unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='c1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_exe_performance_single_amd_pw_m2unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='m2unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_exe_performance_single_amd_pw_f1unt = df_exe_performance_single_amd[df_exe_performance_single_amd['codu']=='f1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_exe_performance_single_intel_pw_c1unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='c1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_exe_performance_single_intel_pw_m2unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='m2unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_exe_performance_single_intel_pw_f1unt = df_exe_performance_single_intel[df_exe_performance_single_intel['codu']=='f1unt']\
.groupby(['UL','exe']).max().reset_index().groupby(['UL']).std().reset_index()
df_result = pd.concat([df_exe_performance_single_amd_pw_c1unt,\
df_exe_performance_single_amd_pw_m2unt['seconds'],\
df_exe_performance_single_amd_pw_f1unt['seconds'],\
df_exe_performance_single_intel_pw_c1unt['seconds'],\
df_exe_performance_single_intel_pw_m2unt['seconds'],\
df_exe_performance_single_intel_pw_f1unt['seconds']],\
axis=1)
df_result.columns = ['UL', 'AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu', 'Intel mem', 'Intel disk']
display (df_result,'Performance-single')
aux=df_result.plot(x= ['UL'],y=['AMD cpu', 'AMD mem', 'AMD disk', 'Intel cpu',\
'Intel mem', 'Intel disk'])
aux.set_xlabel("Utilization level (%)")
aux.set_ylabel("Makespan (s)")
### iqr calculation example
CPU100 = df_exe_energy_single_amd[df_exe_energy_single_amd['cod_x']=='c1l100']
iqr = CPU100["power_average"].quantile(0.75) - CPU100["power_average"].quantile(0.25)
display(iqr)