Skip to content
  • Lukasz Luba's avatar
    PM: EM: Increase energy calculation precision · 60b3fa3f
    Lukasz Luba authored and Ionela Voinescu's avatar Ionela Voinescu committed
    The Energy Model (EM) provides useful information about device power in
    each performance state to other subsystems like: Energy Aware Scheduler
    (EAS). The energy calculation in EAS does arithmetic operation based on
    the EM em_cpu_energy(). Current implementation of that function uses
    em_perf_state::cost as a pre-computed cost coefficient equal to:
    cost = power * max_frequency / frequency.
    The 'power' is expressed in milli-Watts (or in abstract scale).
    
    There are corner cases when the EAS energy calculation for two Performance
    Domains (PDs) return the same value. The EAS compares these values to
    choose smaller one. It might happen that this values are equal due to
    rounding error. In such scenario, we need better resolution, e.g. 1000
    times better. To provide this possibility increase the resolution in the
    em_perf_state::cost for 64-bit architectures. The costs for increasing
    resolution in 32-bit architectures are pretty high (64-bit division) and
    the returns do not justify the increased costs.
    
    This patch allows to avoid the rounding to milli-Watt errors, which might
    occur in EAS energy estimation for each Performance Domains (PD). The
    rounding error is common for small tasks which have small utilization
    value.
    
    There are two places in the code where it makes a difference:
    1. In the find_energy_efficient_cpu() where we are searching for
    best_delta. We might suffer there when two PDs return the same result,
    like in the example below.
    
    Scenario:
    Low utilized system e.g. ~200 sum_util for PD0 and ~220 for PD1. There
    are quite a few small tasks ~10-15 util. These tasks would suffer for
    the rounding error. Such system utilization has been seen while playing
    some simple games. In such condition our partner reported 5..10mA less
    battery drain.
    
    Some details:
    We have two Perf Domains (PDs): PD0 (big) and PD1 (little)
    Let's compare w/o patch set ('old') and w/ patch set ('new')
    We are comparing energy w/ task and w/o task placed in the PDs
    
    a) 'old' w/o patch set, PD0
    task_util = 13
    cost = 480
    sum_util_w/o_task = 215
    sum_util_w_task = 228
    scale_cpu = 1024
    energy_w/o_task = 480 * 215 / 1024 = 100.78 => 100
    energy_w_task = 480 * 228 / 1024 = 106.87 => 106
    energy_diff = 106 - 100 = 6
    (this is equal to 'old' PD1's energy_diff in 'c)')
    
    b) 'new' w/ patch set, PD0
    task_util = 13
    cost = 480 * 1000 = 480000
    sum_util_w/o_task = 215
    sum_util_w_task = 228
    energy_w/o_task = 480000 * 215 / 1024 = 100781
    energy_w_task = 480000 * 228 / 1024  = 106875
    energy_diff = 106875 - 100781 = 6094
    (this is not equal to 'new' PD1's energy_diff in 'd)')
    
    c) 'old' w/o patch set, PD1
    task_util = 13
    cost = 160
    sum_util_w/o_task = 283
    sum_util_w_task = 293
    scale_cpu = 355
    energy_w/o_task = 160 * 283 / 355 = 127.55 => 127
    energy_w_task = 160 * 296 / 355 = 133.41 => 133
    energy_diff = 133 - 127 = 6
    (this is equal to 'old' PD0's energy_diff in 'a)')
    
    d) 'new' w/ patch set, PD1
    task_util = 13
    cost = 160 * 1000 = 160000
    sum_util_w/o_task = 283
    sum_util_w_task = 293
    scale_cpu = 355
    energy_w/o_task = 160000 * 283 / 355 = 127549
    energy_w_task = 160000 * 296 / 355 =   133408
    energy_diff = 133408 - 127549 = 5859
    (this is not equal to 'new' PD0's energy_diff in 'b)')
    
    2. Difference in the the last find_energy_efficient_cpu(): margin filter.
    With this patch the margin comparison also has better resolution,
    so it's possible to have better task placement thanks to that.
    
    Fixes: 27871f7a
    
     ("PM: Introduce an Energy Model management framework")
    Reported-by: default avatarCCJ Yeh <CCj.Yeh@mediatek.com>
    Signed-off-by: default avatarLukasz Luba <lukasz.luba@arm.com>
    60b3fa3f