aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2017-10-16 14:18:11 -0700
committerMarissa Wall <marissaw@google.com>2017-11-29 12:11:01 -0800
commit711d4e90da23c5deedf78a9bee37bbba83c22514 (patch)
tree79a41e027c575059a3ced2534c48f95c7c25c4de
parentedd4cac0d4abbd69d75918cd02013893f73c6333 (diff)
downloadlisa-711d4e90da23c5deedf78a9bee37bbba83c22514.tar.gz
experiments/power: add active and cluster costs
Add measurements that can be used to calculate active costs and accurate cluster costs. These measurements can be used by EAS and the power profile to model cpu power. Test: ./run_cpu_frequency.py Change-Id: I225b388fa4bab9dfc28715f9dada08df936bcb87
-rwxr-xr-xexperiments/power/eas/run_cpu_frequency.py106
1 files changed, 89 insertions, 17 deletions
diff --git a/experiments/power/eas/run_cpu_frequency.py b/experiments/power/eas/run_cpu_frequency.py
index 8cf9910..9780ec7 100755
--- a/experiments/power/eas/run_cpu_frequency.py
+++ b/experiments/power/eas/run_cpu_frequency.py
@@ -69,9 +69,29 @@ def update_cpus(target, on_cpus, off_cpus):
for cpu in off_cpus:
target.hotplug.offline(cpu)
+def run_dhrystone(target, dhrystone, outdir, energy, samples, on_cpus):
+ # Run dhrystone benchmark for longer than the requested time so
+ # we have extra time to set up the measuring device
+ for on_cpu in on_cpus:
+ target.execute('nohup taskset {:x} {} -t {} -r {} 2>/dev/null 1>/dev/null &'.format(1 << (on_cpu), dhrystone, 1, args.duration_s+30))
+
+ # Start measuring
+ te.emeter.reset()
+
+ # Sleep for the required time
+ sleep(args.duration_s)
+
+ # Stop measuring
+ te.emeter.report(outdir, out_energy=energy, out_samples=samples)
+
+ # Since we are using nohup, the benchmark doesn't show up in
+ # process list. Instead sleep until we can be sure the benchmark
+ # is dead.
+ sleep(30)
+
def single_cluster(cpus, sandbox_cg, isolated_cg, dhrystone, outdir):
# For each cluster
- for i, cluster in enumerate(clusters):
+ for i, cluster in enumerate(CLUSTERS):
# For each frequency on the cluster
for freq in target.cpufreq.list_frequencies(cluster[0]):
@@ -103,28 +123,77 @@ def single_cluster(cpus, sandbox_cg, isolated_cg, dhrystone, outdir):
sandbox_cg.set(cpus=on_cpus)
isolated_cg.set(cpus=off_cpus)
- # Run dhrystone benchmark for longer than the requested time so
- # we have extra time to set up the measuring device
- for on_cpu in on_cpus:
- target.execute('nohup taskset {:x} {} -t {} -r {} 2>/dev/null 1>/dev/null &'.format(1 << (on_cpu), dhrystone, 1, args.duration_s+30))
+ # Run the benchmark
+ run_dhrystone(target, dhrystone, outdir, energy, samples, on_cpus)
+
+ # Restore all the cpus
+ target.hotplug.online_all()
+
+
+def multiple_clusters(cpus, sandbox_cg, isolated_cg, dhrystone, outdir):
+ # Keep track of offline and online cpus
+ off_cpus = cpus[:]
+ on_cpus = []
+ prefix = ''
+
+ if len(CLUSTERS) != 2:
+ print 'Only 2 clusters is supported.'
+ return
+
+ # For each cluster
+ for i, cluster in enumerate(CLUSTERS):
+ # A cpu in each cluster
+ cpu = cluster[0]
- # Start measuring
- te.emeter.reset()
+ freq = target.cpufreq.list_frequencies(cpu)[0]
- # Sleep for the required time
- sleep(args.duration_s)
+ # Set frequency to min
+ target.cpufreq.set_frequency(cpu, freq)
- # Stop measuring
- te.emeter.report(outdir, out_energy=energy, out_samples=samples)
+ # Keep cpu on
+ on_cpus.append(cpu)
+ off_cpus.remove(cpu)
- # Since we are using nohup, the benchmark doesn't show up in
- # process list. Instead sleep until we can be sure the benchmark
- # is dead.
- sleep(30)
+ prefix = '{}cluster{}-cores{}-freq{}_'.format(prefix, i, cpu, freq)
+
+ # Update cgroups to reflect on_cpus and off_cpus
+ sandbox_cg.set(cpus=on_cpus)
+ isolated_cg.set(cpus=off_cpus)
+
+ # Bring the on_cpus online take the off_cpus offline
+ update_cpus(target, on_cpus, off_cpus)
+
+ # For one cpu in each cluster
+ for i, cpu in enumerate(on_cpus):
+
+ # For each frequency on the cluster
+ for freq in target.cpufreq.list_frequencies(cpu):
+
+ # Switch the output file so the previous samples are not overwritten
+ curr_prefix = prefix.replace('cores{}-freq{}'.format(cpu,
+ target.cpufreq.list_frequencies(cpu)[0]),
+ 'cores{}-freq{}'.format(cpu, freq))
+ samples = '{}samples.csv'.format(curr_prefix)
+ energy = '{}energy.json'.format(curr_prefix)
+
+ # If we are continuing from a previous experiment and this set has
+ # already been run, skip it
+ if args.cont and os.path.isfile(os.path.join(outdir, energy)) and os.path.isfile(os.path.join(outdir, samples)):
+ continue
+
+ # Set frequency
+ target.cpufreq.set_frequency(cpu, freq)
+
+ # Run the benchmark
+ run_dhrystone(target, dhrystone, outdir, energy, samples, on_cpus)
+
+ # Reset frequency to min
+ target.cpufreq.set_frequency(cpu, target.cpufreq.list_frequencies(cpu)[0])
# Restore all the cpus
target.hotplug.online_all()
+
def experiment():
# Check if the dhyrstone binary is on the device
dhrystone = os.path.join(target.executables_directory, 'dhrystone')
@@ -144,8 +213,7 @@ def experiment():
os.makedirs(outdir)
# Get clusters and cpus
- clusters = te.topology.get_level('cluster')
- cpus = [cpu for cluster in clusters for cpu in cluster]
+ cpus = [cpu for cluster in CLUSTERS for cpu in cluster]
# Prevent screen from dozing
Screen.set_doze_always_on(target, on=False)
@@ -179,6 +247,9 @@ def experiment():
# Run measurements on single cluster
single_cluster(cpus, sandbox_cg, isolated_cg, dhrystone, outdir)
+ # Run measurements on multiple clusters
+ multiple_clusters(cpus, sandbox_cg, isolated_cg, dhrystone, outdir)
+
# Restore all governors
for i, governor in enumerate(governors):
target.cpufreq.set_governor(cpus[i], governor)
@@ -241,5 +312,6 @@ if args.serial:
# Initialize a test environment using:
te = TestEnv(my_conf, wipe=False)
target = te.target
+CLUSTERS = te.topology.get_level('cluster')
results = experiment()