diff options
author | Marissa Wall <marissaw@google.com> | 2017-10-16 14:18:11 -0700 |
---|---|---|
committer | Marissa Wall <marissaw@google.com> | 2017-11-29 12:11:01 -0800 |
commit | 711d4e90da23c5deedf78a9bee37bbba83c22514 (patch) | |
tree | 79a41e027c575059a3ced2534c48f95c7c25c4de | |
parent | edd4cac0d4abbd69d75918cd02013893f73c6333 (diff) | |
download | lisa-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-x | experiments/power/eas/run_cpu_frequency.py | 106 |
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() |