In [1]:
import logging
from conf import LisaLogging
LisaLogging.setup()
# Uncomment the follwing line to enabled devlib debugging statements
# logging.getLogger('ssh').setLevel(logging.DEBUG)
In [2]:
# Generate plots inline
%pylab inline
import copy
import json
import os
# Support to access the remote target
import devlib
from env import TestEnv
# Support to configure and run RTApp based workloads
from wlgen import RTA, Periodic
# Support for performance analysis of RTApp workloads
from perf_analysis import PerfAnalysis
# Support for trace events analysis
from trace import Trace
# Suport for FTrace events parsing and visualization
import trappy
In [3]:
# Setup a target configuration
my_target_conf = {
# Define the kind of target platform to use for the experiments
"platform" : 'linux', # Linux system, valid other options are:
# android - access via ADB
# linux - access via SSH
# host - direct access
# Preload settings for a specific target
"board" : 'juno', # load JUNO specific settings, e.g.
# - HWMON based energy sampling
# - Juno energy model
# valid options are:
# - juno - JUNO Development Board
# - tc2 - TC2 Development Board
# - oak - Mediatek MT63xx based target
# Define devlib module to load
"modules" : [
'bl', # enable big.LITTLE support
'cpufreq' # enable CPUFreq support
],
# Account to access the remote target
"host" : '192.168.0.1',
"username" : 'root',
"password" : '',
# Comment the following line to force rt-app calibration on your target
"rtapp-calib" : {
'0': 361, '1': 138, '2': 138, '3': 352, '4': 360, '5': 353
}
}
# Setup the required Test Environment supports
my_tests_conf = {
# Additional devlib modules required for this experiment
"modules" : ['hwmon'],
# Binary tools required to run this experiment
# These tools must be present in the tools/ folder for the architecture
"tools" : ['rt-app', 'taskset', 'trace-cmd'],
# FTrace events end buffer configuration
"ftrace" : {
"events" : [
"sched_switch",
"sched_load_avg_cpu",
"cpu_frequency",
"cpu_capacity"
],
"buffsize" : 10240
},
}
In [4]:
# Initialize a test environment using:
# the provided target configuration (my_target_conf)
# the provided test configuration (my_test_conf)
te = TestEnv(target_conf=my_target_conf, test_conf=my_tests_conf)
target = te.target
In [5]:
logging.info("Target ABI: %s, CPus: %s",
target.abi,
target.cpuinfo.cpu_names)
These are a set of functions to run a workload with different CPUFreq configurations
In [6]:
def set_performance():
target.cpufreq.set_all_governors('performance')
def set_powersave():
target.cpufreq.set_all_governors('powersave')
def set_interactive():
target.cpufreq.set_all_governors('interactive')
def set_sched():
target.cpufreq.set_all_governors('sched')
def set_ondemand():
target.cpufreq.set_all_governors('ondemand')
# Configure the MAX sampling rate supporte by the LITTLE cores
littles_tunables = target.cpufreq.get_governor_tunables(
target.bl.littles[0])
target.cpufreq.set_governor_tunables(
target.bl.littles[0], 'ondemand',
**{'sampling_rate' : littles_tunables['sampling_rate_min']}
)
# Configure the MAX sampling rate supporte by the big cores
bigs_tunables = target.cpufreq.get_governor_tunables(
target.bl.bigs[0])
target.cpufreq.set_governor_tunables(
target.bl.bigs[0], 'ondemand',
**{'sampling_rate' : bigs_tunables['sampling_rate_min']}
)
In [7]:
# CPUFreq configurations to test
confs = {
'performance' : {
'label' : 'prf',
'set' : set_performance,
},
'powersave' : {
'label' : 'pws',
'set' : set_powersave,
},
# 'interactive' : {
# 'label' : 'int',
# 'set' : set_interactive,
# },
'sched' : {
'label' : 'sch',
'set' : set_sched,
},
'ondemand' : {
'label' : 'odm',
'set' : set_ondemand,
}
}
# The set of results forlder for each comparition test
results = {}
In [8]:
def experiment(governor, rtapp, exp_dir):
os.system('mkdir -p {}'.format(exp_dir));
logging.info('------------------------')
logging.info('Run workload using %s governor', governor)
confs[governor]['set']()
# Start FTrace and Energy monitoring
te.ftrace.start()
te.emeter.reset()
# Run the workload
rtapp.run(out_dir=exp_dir)
# Stop FTrace and sample Energy consumption
nrg = te.emeter.report(exp_dir).channels
te.ftrace.stop()
logging.info('Energy: %s', nrg)
# Dump platform description
te.platform_dump(exp_dir)
# Collect and keep track of the trace
trace_file = os.path.join(exp_dir, 'trace.dat')
te.ftrace.get_trace(trace_file)
# Parse trace
tr = Trace(exp_dir,
my_tests_conf['ftrace']['events'],
te.platform)
# return all the experiment data
return {
'dir' : exp_dir,
'energy' : copy.deepcopy(nrg),
'trace' : trace_file,
'tr' : tr,
'ftrace' : tr.ftrace
}
def compare(tid, rtapp):
logging.info('Test case: %s', tid)
res_dir = os.path.join(te.res_dir, tid)
logging.info(' results folder: %s', res_dir)
# Run the workload in all the configured governors
results[tid] = {}
for governor in confs:
test_dir = os.path.join(res_dir, governor)
results[tid][governor] = experiment(governor, rtapp, test_dir)
def plot(tid):
global results
for governor in confs:
plot_title = "{} Governor".format(governor.upper())
trappy.LinePlot(results[tid][governor]['ftrace'],
templates,
column=column,
pivot="cpu",
filters={"cpu": [1]},
marker = '+',
drawstyle='steps-post',
title=plot_title,
ylim=(0, 1100)).view()
for governor in confs:
pa = PerfAnalysis(results[tid][governor]['dir'])
for task in pa.tasks():
pa.plotPerf(task, "Performance using [{}] governor"\
.format(governor))
def report_nrg(tid):
global results
print "{:15s} | {:>9s} {:>9s} {:>9s}"\
.format('Governor', 'A53', 'A57', 'Total')
print "{:-<16s}+{:-<30s}".format('', '')
for governor in confs:
plot_title = "{}".format(governor.upper())
nrg = results[tid][governor]['energy']
nrg_little = float(nrg['little'])
nrg_big = float(nrg['big'])
nrg_sum = nrg_little + nrg_big
print "{:15s} | {:9.3f} {:9.3f} {:9.3f}"\
.format(governor, nrg_little, nrg_big, nrg_sum)
In [9]:
# Define a label for this test case
test_case = 'light-heavy-light'
cpus = str(target.bl.bigs_online[0])
light1 = Periodic(duty_cycle_pct=10, duration_s=1.0, period_ms= 10,
cpus=cpus)
heavy1 = Periodic(duty_cycle_pct=90, duration_s=0.1, period_ms=100,
cpus=cpus)
light2 = Periodic(duty_cycle_pct=10, duration_s=1.0, period_ms= 10,
cpus=cpus)
lhl_task = light1 + heavy1 + light2
rtapp = RTA(target, 'smoke', calibration=te.calibration())
rtapp.conf(
kind='profile',
params={
'task1' : lhl_task.get()
},
run_dir=target.working_directory
);
In [10]:
# Run this workload in all the configurations
compare(test_case, rtapp)
In [11]:
# Plot all data collected from experiments
def plot(tid):
global results
# Plot CPU LoadAvg and Capacity (for CPU0)
for governor in confs:
plot_title = "{} Governor".format(governor.upper())
trappy.LinePlot(results[tid][governor]['ftrace'],
signals=[
"sched_load_avg_cpu:util_avg",
"cpu_capacity:capacity"],
pivot="cpu",
filters={"cpu": [1]},
marker = '+',
drawstyle='steps-post',
title=plot_title,
ylim=(0, 1100)).view()
# Plot Custer Frequencies and report averate frequencies
for governor in confs:
plot_title = "Cluster frequencies, {}".format(governor.upper())
trace = results[tid][governor]['tr']
logging.info("%s:", plot_title)
trace.analysis.frequency.plotClusterFrequencies(title=plot_title)
# Plot RTApp performance index
for governor in confs:
plot_title = "RTApp performances, {}".format(governor.upper())
pa = PerfAnalysis(results[tid][governor]['dir'])
logging.info("%s:", plot_title)
for task in pa.tasks():
pa.plotPerf(task, "Performance using [{}] governor"\
.format(governor))
In [12]:
plot(test_case)
In [13]:
report_nrg(test_case)
In [14]:
# Define a label for this test case
test_case = 'light-heavy-medium'
light1 = Periodic(duty_cycle_pct=10, duration_s=1.0, period_ms= 10,
cpus=str(target.bl.bigs_online[0]))
heavy1 = Periodic(duty_cycle_pct=90, duration_s=0.1, period_ms=100)
mdium1 = Periodic(duty_cycle_pct=50, duration_s=1.0, period_ms= 10)
lhm_task = light1 + heavy1 + mdium1
rtapp = RTA(target, 'smoke', calibration=te.calibration())
rtapp.conf(
kind='profile',
params={
'task1' : lhm_task.get()
},
run_dir=target.working_directory
);
In [15]:
# Run this workload in all the configurations
compare(test_case, rtapp)
In [16]:
plot(test_case)
In [17]:
report_nrg(test_case)