Heartbeats now on crates.io.

Updates to energymon interface for energy profiling.
Profiling script for Android.
This commit is contained in:
Connor Imes 2016-03-08 13:48:30 -06:00
parent 0f526054eb
commit f31e8841fb
8 changed files with 236 additions and 50 deletions

View file

@ -23,7 +23,7 @@ HEARTBEAT_PROFILER_CATEGORIES = [
("Compositing", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutPerform", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutStyleRecalc", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutTextShaping", HEARTBEAT_DEFAULT_WINDOW_SIZE),
# ("LayoutTextShaping", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutRestyleDamagePropagation", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutNonIncrementalReset", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("LayoutSelectorMatch", HEARTBEAT_DEFAULT_WINDOW_SIZE),
@ -56,7 +56,7 @@ HEARTBEAT_PROFILER_CATEGORIES = [
("ScriptWorkerEvent", HEARTBEAT_DEFAULT_WINDOW_SIZE),
("ApplicationHeartbeat", 100),
]
ENERGY_READER_BIN = "energymon"
ENERGY_READER_BIN = "energymon-file-provider"
ENERGY_READER_TEMP_OUTPUT = "energymon.txt"
SUMMARY_OUTPUT = "summary.txt"
@ -179,7 +179,7 @@ def main():
# Default benchmark
benchmark = path.join(TOP_DIR, "tests", "html", "perf-rainbow.html")
# Default renderer
renderer = "-c"
renderer = ""
# Default output directory
output_dir = "heartbeat_logs"
# Default build target
@ -199,9 +199,9 @@ def main():
parser.add_argument("-d", "--debug",
action='store_true',
help="Use debug build instead of release build")
parser.add_argument("-g", "--gpu",
parser.add_argument("-w", "--webrender",
action='store_true',
help="Rendering with GPU instead of CPU")
help="Use webrender backend")
parser.add_argument("-l", "--max_layout_threads",
help="Specify the maximum number of threads for layout, for example \"-l 5\"")
parser.add_argument("-o", "--output",
@ -222,8 +222,8 @@ def main():
benchmark = args.benchmark
if args.debug:
build_target = "debug"
if args.gpu:
renderer = "-g"
if args.webrender:
renderer = "-w"
if args.max_layout_threads:
max_layout_threads = int(args.max_layout_threads)
if args.output:

View file

@ -0,0 +1,119 @@
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import sys
import os
from os import path
import time
import datetime
import argparse
import subprocess
TOP_DIR = path.join("..", "..")
GUARD_TIME = 20
SUMMARY_OUTPUT = "summary.txt"
def get_command(layout_thread_count, renderer, page, profile):
"""Get the command to execute.
"""
return path.join(TOP_DIR, "mach") + " run --android" + \
" -p %d -o /sdcard/servo/output.png -y %d %s -Z profile-script-events,profile-heartbeats '%s'" % \
(profile, layout_thread_count, renderer, page)
def git_rev_hash():
"""Get the git revision hash.
"""
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).rstrip()
def git_rev_hash_short():
"""Get the git revision short hash.
"""
return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).rstrip()
def execute(base_dir, renderer, page, profile, trial, layout_thread_count):
"""Run a single execution.
"""
log_dir = path.join(base_dir, "logs_l" + str(layout_thread_count),
"trial_" + str(trial))
if os.path.exists(log_dir):
print "Log directory already exists: " + log_dir
sys.exit(1)
os.makedirs(log_dir)
# Execute
cmd = get_command(layout_thread_count, renderer, page, profile)
print cmd
os.system(cmd)
print 'sleep ' + str(GUARD_TIME)
time.sleep(GUARD_TIME)
# Write a file that describes this execution
with open(path.join(log_dir, SUMMARY_OUTPUT), "w") as f:
f.write("Datetime (UTC): " + datetime.datetime.utcnow().isoformat())
f.write("\nPlatform: Android")
f.write("\nGit hash: " + git_rev_hash())
f.write("\nGit short hash: " + git_rev_hash_short())
f.write("\nLayout threads: " + str(layout_thread_count))
f.write("\nTrial: " + str(trial))
f.write("\nCommand: " + cmd)
def main():
"""For this script to be useful, the following conditions are needed:
- Build servo for Android in release mode with the "energy-profiling" feature enabled.
"""
# Default number of layout threads
layout_threads = 1
# Default benchmark
benchmark = "https://www.mozilla.org/"
# Default renderer
renderer = ""
# Default output directory
output_dir = "heartbeat_logs"
# Default profile interval
profile = 60
# Parsing the input of the script
parser = argparse.ArgumentParser(description="Characterize Servo timing and energy behavior on Android")
parser.add_argument("-b", "--benchmark",
default=benchmark,
help="Gets the benchmark, for example \"-b http://www.example.com\"")
parser.add_argument("-w", "--webrender",
action='store_true',
help="Use webrender backend")
parser.add_argument("-l", "--layout_threads",
help="Specify the number of threads for layout, for example \"-l 5\"")
parser.add_argument("-o", "--output",
help="Specify the log output directory, for example \"-o heartbeat_logs\"")
parser.add_argument("-p", "--profile",
default=60,
help="Profiler output interval, for example \"-p 60\"")
args = parser.parse_args()
if args.benchmark:
benchmark = args.benchmark
if args.webrender:
renderer = "-w"
if args.layout_threads:
layout_threads = int(args.layout_threads)
if args.output:
output_dir = args.output
if args.profile:
profile = args.profile
if os.path.exists(output_dir):
print "Output directory already exists: " + output_dir
sys.exit(1)
os.makedirs(output_dir)
execute(output_dir, renderer, benchmark, profile, 1, layout_threads)
if __name__ == "__main__":
main()

View file

@ -359,6 +359,8 @@ def main():
directory = 'heartbeat_logs'
# Default output directory
output_dir = 'plots'
# Default android
android = False
# Parsing the input of the script
parser = argparse.ArgumentParser(description="Process Heartbeat log files from characterization")
@ -368,12 +370,19 @@ def main():
parser.add_argument("-o", "--output",
default=output_dir,
help="Specify the log output directory, for example \"-o plots\"")
parser.add_argument("--android",
action="store_true",
dest="android",
default=False,
help="Specify if processing results from Android")
args = parser.parse_args()
if args.directory:
directory = args.directory
if args.output:
output_dir = args.output
if args.android:
android = args.android
if not os.path.exists(directory):
print "Input directory does not exist: " + directory
@ -385,10 +394,11 @@ def main():
res = process_logs(directory)
best = find_best_executions(directory)
print 'Best time:', best[0]
print 'Best energy:', best[1]
print 'Best power:', best[2]
if not android:
best = find_best_executions(directory)
print 'Best time:', best[0]
print 'Best energy:', best[1]
print 'Best power:', best[2]
os.makedirs(output_dir)
plot_all_raw_totals(res, output_dir)