lisa.energy_model.EnergyModel#
- class lisa.energy_model.EnergyModel(root_node, root_power_domain, freq_domains)[source]#
Bases:
Serializable
,Loggable
Represents hierarchical CPU topology with power and capacity data
An energy model consists of
A CPU topology, representing the physical (cache/interconnect) topology of the CPUs. Each node stores the energy usage of that node’s hardware when it is in each active or idle state. They also store a compute capacity at each frequency, but this is only meaningful for leaf nodes (CPUs) and may be None at higher levels. These capacity values are relative; the maximum capacity would usually be 1024, the value of SCHED_CAPACITY_SCALE in the Linux kernel scheduler. Use EnergyModelNodes to describe this.
A power domain topology, representing the hierarchy of areas that can be powered down (idled). The power domains are a single tree. Leaf nodes must contain exactly one CPU and the root node must indirectly contain every CPU. Each power domain has a list (maybe empty) of names of idle states that that domain can enter. Use PowerDomains to describe this.
A set of frequency domains, representing groups of CPUs whose clock frequencies must be equal (probably because they share a clock). The frequency domains must be a partition of the CPUs.
- Parameters:
root_node – Root of
EnergyModelNode
treeroot_power_domain – Root of
PowerDomain
treefreq_domains – Collection of collections of logical CPU numbers representing frequency (clock) domains.
Note
The most signficant shortcomings of the model are:
Voltage domains are assumed to be congruent to frequency domains
Idle state power is assumed to be independent of voltage
Temperature is ignored entirely
cpu_utils
: CPU util distributionsUsed throughout this module: A
cpu_utils
is a listu
whereu[N]
is the sum of the frequency-invariant, capacity-invariant utilization of tasks placed on CPU N. That is, the quantity represented by a CPU runqueue’s util_avg in the Linux kernel scheduler’s load-tracking system with EAS features enabled.This represents a static utilization, assuming that tasks don’t change in size (for example representing a set of fixed periodic RT-App workloads). For workloads that change over time, a series of
cpu_utils
items would be needed to describe the utilization, with a distinct estimation for each item in the series.Warning
Arbitrary code can be executed while loading an instance from a YAML or Pickle file. To include untrusted data in YAML, use the !untrusted tag along with a string
Attributes
The relative computational capacity of the most powerful CPU at its highest available frequency. Utilisation is in the interval
[0, capacity_scale]
.List of leaf (CPU)
EnergyModelNode
.List of logical CPU numbers in the system.
ATTRIBUTES_SERIALIZATION
inheritedAttributes to be treated specially during serialization.
DEFAULT_SERIALIZATION_FMT
inheritedDefault format used when serializing objects.
YAML_ENCODING
inheritedEncoding used for YAML files.
Properties
The CPUs with the highest compute capacity at their highest frequency.
List of lists of CPUs who share the same active state values.
True iff CPUs do not all have the same efficiency and OPP range.
The CPUs with the lowest compute capacity at their highest frequency.
List of lists of CPUs nodes who share the same active state values.
logger
inheritedConvenience short-hand for
self.get_logger()
.Methods
Estimate the energy usage of the system under a utilization distribution.
Estimate the energy consumption of the system by looking at a trace.
Create an instance of (a subclass of) :class:
EnergyModel
by reading a target filesystem.Convenience method to get the capacity of a CPU at a given frequency.
Find the optimal distribution of work for a set of tasks.
Work out CPU frequencies required to execute a workload.
Pessimistically guess the idle states that each CPU may enter.
Check if an
EnergyModel
can be loaded from the target.__copy__()
inheritedRegular shallow copy operation, without dropping any attributes.
__getstate__()
inheritedFilter the instance’s attributes upon serialization.
__setstate__()
inheritedfrom_path()
inheritedDeserialize an object from a file.
get_logger()
inheritedProvides a
logging.Logger
named aftercls
.log_locals()
inheritedDebugging aid: log the local variables of the calling function.
to_path()
inheritedSerialize the object to a file.
to_yaml()
inheritedReturn a YAML string with the serialized object.
Attributes#
- EnergyModel.capacity_scale#
The relative computational capacity of the most powerful CPU at its highest available frequency. Utilisation is in the interval
[0, capacity_scale]
.
- EnergyModel.cpu_nodes#
List of leaf (CPU)
EnergyModelNode
- EnergyModel.cpus#
List of logical CPU numbers in the system
- EnergyModel.ATTRIBUTES_SERIALIZATION = {'allowed': [], 'ignored': [], 'placeholders': {}}#
Inherited attribute, see
lisa.utils.Serializable.ATTRIBUTES_SERIALIZATION
Attributes to be treated specially during serialization.
- EnergyModel.DEFAULT_SERIALIZATION_FMT = 'yaml'#
Inherited attribute, see
lisa.utils.Serializable.DEFAULT_SERIALIZATION_FMT
Default format used when serializing objects.
- EnergyModel.YAML_ENCODING = 'utf-8'#
Inherited attribute, see
lisa.utils.Serializable.YAML_ENCODING
Encoding used for YAML files.
Properties#
- property EnergyModel.biggest_cpus[source]#
The CPUs with the highest compute capacity at their highest frequency
- property EnergyModel.cpu_groups[source]#
List of lists of CPUs who share the same active state values
- property EnergyModel.is_heterogeneous[source]#
True iff CPUs do not all have the same efficiency and OPP range
- property EnergyModel.littlest_cpus[source]#
The CPUs with the lowest compute capacity at their highest frequency
- property EnergyModel.node_groups[source]#
List of lists of CPUs nodes who share the same active state values
- property EnergyModel.logger#
Inherited property, see
lisa.utils.Loggable.logger
Convenience short-hand for
self.get_logger()
.
Methods#
- EnergyModel.estimate_from_cpu_util(cpu_utils, freqs=None, idle_states=None)[source]#
Estimate the energy usage of the system under a utilization distribution
Optionally also take freqs; a list of frequencies at which each CPU is assumed to run, and idle_states, the idle states that each CPU can enter between activations. If not provided, they will be estimated assuming an ideal selection system (i.e. perfect cpufreq & cpuidle governors).
- Parameters:
cpu_utils – Utilization distribution, see cpu_utils
freqs – List of CPU frequencies. Got from
guess_freqs()
by default.idle_states – List of CPU frequencies. Got from
guess_idle_states()
by default.
- Returns:
Dict with power in bogo-Watts (bW), with contributions from each system component keyed with a tuple of the CPUs comprising that component (i.e. :attr:EnergyModelNode.cpus)
{ (0,) : 10, (1,) : 10, (0, 1) : 5, }
This represents CPUs 0 and 1 each using 10bW and their shared resources using 5bW for a total of 25bW.
- EnergyModel.estimate_from_trace(trace)[source]#
Estimate the energy consumption of the system by looking at a trace
It uses the EAS energy model data, and the idle and DVFS conditions reported in the trace, to estimate the energy usage of the system at every given moment.
Takes into account knowledge of power domains - where cpuidle makes impossible claims about idle states (e.g. a CPU in ‘cluster sleep’ while its cluster siblings are running), the states will be minimised.
The accuracy of this is otherwise totally dependent on the accuracy of the EAS energy model and the kernel’s information. This does not take into account cost of idle state of DVFS transitions, nor any other conditions that are invisible to the kernel. The effect any power decisions that the platform makes independently of the kernel cannot be seen in this data. Examples of this _might_ include firmware thermal management invisibly restricting CPU frequencies, or secure-world software with real-time constraints preventing deep CPU idle states.
- Parameters:
trace (lisa.trace.Trace) – The trace
- Returns:
A DataFrame with a column for each node in the energy model, labelled with the CPU members of the node joined by ‘-‘s. Shows the energy use by each node at each given moment. If you don’t care about those details, call
.sum(axis=1)
on the returned DataFrame to get a Series that shows overall estimated power usage over time.- Required trace events:
cpu_frequency
oruserspace@cpu_frequency_devlib
cpu_idle
- classmethod EnergyModel.from_target(target)[source]#
Create an instance of (a subclass of) :class:
EnergyModel
by reading a target filesystem.- Parameters:
target (devlib.target.Target) – Target object to read filesystem from.
- Returns:
A instance of a subclass of
EnergyModel
.
- EnergyModel.get_cpu_capacity(cpu, freq=None)[source]#
Convenience method to get the capacity of a CPU at a given frequency
- Parameters:
cpu – CPU to get capacity for
freq – Frequency to get the CPU capacity at. Default is max capacity.
- EnergyModel.get_optimal_placements(capacities, capacity_margin_pct=0)[source]#
Find the optimal distribution of work for a set of tasks
Find a list of candidates which are estimated to be optimal in terms of power consumption, but that do not result in any CPU becoming over-utilized.
If no such candidates exist, i.e. the system being modeled cannot satisfy the workload’s throughput requirements, an
EnergyModelCapacityError
is raised. For example, if e was an EnergyModel modeling two CPUs with capacity 1024, this error would be raised by:e.get_optimal_placements({"t1": 800, "t2": 800, "t3: "800"})
This estimation assumes an ideal system of selecting OPPs and idle states for CPUs.
Note
This is a brute force search taking time exponential wrt. the number of tasks.
- Parameters:
capacities – Dict mapping tasks to expected utilization values. These tasks are assumed not to change; they have a single static utilization value. A set of single-phase periodic RT-App tasks is an example of a suitable workload for this model.
capacity_margin_pct – Capacity margin before overutilizing a CPU
- Returns:
List of
cpu_utils
items representing distributions of work under optimal task placements, see cpu_utils. Multiple task placements that result in the same CPU utilizations are considered equivalent.
- EnergyModel.guess_freqs(cpu_utils, capacity_margin_pct=0)[source]#
Work out CPU frequencies required to execute a workload
Find the lowest possible frequency for each CPU that provides enough capacity to satisfy the utilization, taking into account frequency domains.
- Parameters:
cpu_utils – Utilization distribution, see cpu_utils
capacity_margin_pct – Capacity margin before overutilizing a CPU
- Returns:
List
ret
whereret[N]
is the frequency that CPU N must run at
- EnergyModel.guess_idle_states(cpus_active)[source]#
Pessimistically guess the idle states that each CPU may enter
If a CPU has any tasks it is estimated that it may only enter its shallowest idle state in between task activations. If all the CPUs within a power domain have no tasks, they will all be judged able to enter that domain’s deepest idle state. If any CPU in a domain has work, no CPUs in that domain are assumed to enter any domain shared state.
e.g. Consider a system with
two power domains PD0 and PD1
4 CPUs, with CPUs [0, 1] in PD0 and CPUs [2, 3] in PD1
4 idle states: “WFI”, “cpu-sleep”, “cluster-sleep-0” and “cluster-sleep-1”, where the “cluster-sleep-*” states domain states, i.e. a CPU can only enter those states when both CPUs in the domain are idle.
Then here are some example inputs and outputs:
# All CPUs idle: [0, 0, 0, 0] -> ["cluster-sleep-1", "cluster-sleep-1", "cluster-sleep-1", "cluster-sleep-1"] # All CPUs have work [1, 1, 1, 1] -> ["WFI","WFI","WFI", "WFI"] # One power domain active, the other idle [0, 0, 1, 1] -> ["cluster-sleep-1", "cluster-sleep-1", "WFI","WFI"] # One CPU active. # Note that CPU 2 has no work but is assumed to never be able to enter # any "cluster" state. [0, 0, 0, 1] -> ["cluster-sleep-1", "cluster-sleep-1", "cpu-sleep","WFI"]
- Parameters:
cpus_active – list where bool(cpus_active[N]) is False iff no tasks will run on CPU N.
- Returns:
List
ret
whereret[N]
is the name of the estimated idle state that CPU N can enter during idle periods.
- classmethod EnergyModel.probe_target(target)[source]#
Check if an
EnergyModel
can be loaded from the target.- Parameters:
target (devlib.target.Target) – Target to look at.
- EnergyModel.__copy__()#
Inherited method, see
lisa.utils.Serializable.__copy__()
Regular shallow copy operation, without dropping any attributes.
- EnergyModel.__getstate__()#
Inherited method, see
lisa.utils.Serializable.__getstate__()
Filter the instance’s attributes upon serialization.
- EnergyModel.__setstate__(dct)#
Inherited method, see
lisa.utils.Serializable.__setstate__()
- classmethod EnergyModel.from_path(filepath, fmt=None)#
Inherited method, see
lisa.utils.Serializable.from_path()
Deserialize an object from a file.
- classmethod EnergyModel.get_logger(suffix=None)#
Inherited method, see
lisa.utils.Loggable.get_logger()
Provides a
logging.Logger
named aftercls
.
- classmethod EnergyModel.log_locals(var_names=None, level='debug')#
Inherited method, see
lisa.utils.Loggable.log_locals()
Debugging aid: log the local variables of the calling function.
- EnergyModel.to_path(filepath, fmt=None)#
Inherited method, see
lisa.utils.Serializable.to_path()
Serialize the object to a file.
- EnergyModel.to_yaml()#
Inherited method, see
lisa.utils.Serializable.to_yaml()
Return a YAML string with the serialized object.
- static EnergyModel.from_debugfsEM_target(*args, **kwargs)[source]#
See
LinuxEnergyModel.from_target()
Deprecated since version 2.0.
from_debugfsEM_target()
is deprecated and will be removed in version 4.0, use lisa.energy_model.LinuxEnergyModel.from_target instead
- static EnergyModel.from_sd_target(*args, **kwargs)[source]#
See
LegacyEnergyModel.from_target()
Deprecated since version 2.0.
from_sd_target()
is deprecated and will be removed in version 4.0, use lisa.energy_model.LegacyEnergyModel.from_target instead