On Friday, August 28, 2020, Ahmed Karaman <ahmedkhaledkara...@gmail.com> wrote:
> - Apply pylint and flake8 formatting rules to the script. > - Move syntax and usage exmaple to main() docstring. > - Update get_jit_line() to only detect the main jit call. > - Use mypy for specifying parameters and return types in functions. > > Reviewed-by: Aleksandar Markovic <aleksandar.qemu.de...@gmail.com> > Signed-off-by: Ahmed Karaman <ahmedkhaledkara...@gmail.com> > --- > scripts/performance/dissect.py | 123 ++++++++++++++++++--------------- > 1 file changed, 68 insertions(+), 55 deletions(-) > > diff --git a/scripts/performance/dissect.py b/scripts/performance/dissect. > py > index bf24f50922..d4df884b75 100755 > --- a/scripts/performance/dissect.py > +++ b/scripts/performance/dissect.py > @@ -1,34 +1,27 @@ > #!/usr/bin/env python3 > > -# Print the percentage of instructions spent in each phase of QEMU > -# execution. > -# > -# Syntax: > -# dissect.py [-h] -- <qemu executable> [<qemu executable options>] \ > -# <target executable> [<target executable options>] > -# > -# [-h] - Print the script arguments help message. > -# > -# Example of usage: > -# dissect.py -- qemu-arm coulomb_double-arm > -# > -# This file is a part of the project "TCG Continuous Benchmarking". > -# > -# Copyright (C) 2020 Ahmed Karaman <ahmedkhaledkara...@gmail.com> > -# Copyright (C) 2020 Aleksandar Markovic <aleksandar.qemu.devel@gmail. > com> > -# > -# This program is free software: you can redistribute it and/or modify > -# it under the terms of the GNU General Public License as published by > -# the Free Software Foundation, either version 2 of the License, or > -# (at your option) any later version. > -# > -# This program is distributed in the hope that it will be useful, > -# but WITHOUT ANY WARRANTY; without even the implied warranty of > -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > -# GNU General Public License for more details. > -# > -# You should have received a copy of the GNU General Public License > -# along with this program. If not, see <https://www.gnu.org/licenses/>. > +""" > +Print the percentage of instructions spent in each phase of QEMU > +execution. > + > +This file is a part of the project "TCG Continuous Benchmarking". > + > +Copyright (C) 2020 Ahmed Karaman <ahmedkhaledkara...@gmail.com> > +Copyright (C) 2020 Aleksandar Markovic <aleksandar.qemu.de...@gmail.com> > + > +This program is free software: you can redistribute it and/or modify > +it under the terms of the GNU General Public License as published by > +the Free Software Foundation, either version 2 of the License, or > +(at your option) any later version. > + > +This program is distributed in the hope that it will be useful, > +but WITHOUT ANY WARRANTY; without even the implied warranty of > +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +GNU General Public License for more details. > + > +You should have received a copy of the GNU General Public License > +along with this program. If not, see <https://www.gnu.org/licenses/>. > +""" > > import argparse > import os > @@ -36,23 +29,26 @@ import subprocess > import sys > import tempfile > > +from typing import List > + > > -def get_JIT_line(callgrind_data): > +def get_jit_line(callgrind_data: List[str]) -> int: > """ > Search for the first instance of the JIT call in > the callgrind_annotate output when ran using --tree=caller > This is equivalent to the self number of instructions of JIT. > > Parameters: > - callgrind_data (list): callgrind_annotate output > + callgrind_data (List[str]): callgrind_annotate output > > Returns: > (int): Line number > """ > line = -1 > - for i in range(len(callgrind_data)): > - if callgrind_data[i].strip('\n') and \ > - callgrind_data[i].split()[-1] == "[???]": > + for (i, callgrind_datum) in enumerate(callgrind_data): > + if callgrind_datum.strip('\n') and \ > + callgrind_datum.split()[-1] == "[???]" and \ > + callgrind_datum.split()[1] == "*": > line = i > break > if line == -1: > @@ -61,6 +57,18 @@ def get_JIT_line(callgrind_data): > > > def main(): > + """ > + Parse the command line arguments then start the execution. > + Syntax: > + dissect.py [-h] -- <qemu executable> [<qemu executable options>] \ > + <target executable> [<target executable options>] > + > + [-h] - Print the script arguments help message. > + > + Example of usage: > + dissect.py -- qemu-arm coulomb_double-arm > + """ > + > # Parse the command line arguments > parser = argparse.ArgumentParser( > usage='dissect.py [-h] -- ' > @@ -76,7 +84,7 @@ def main(): > > # Insure that valgrind is installed > check_valgrind = subprocess.run( > - ["which", "valgrind"], stdout=subprocess.DEVNULL) > + ["which", "valgrind"], stdout=subprocess.DEVNULL, check=False) > if check_valgrind.returncode: > sys.exit("Please install valgrind before running the script.") > > @@ -93,7 +101,8 @@ def main(): > "--callgrind-out-file=" + data_path] > + command), > stdout=subprocess.DEVNULL, > - stderr=subprocess.PIPE) > + stderr=subprocess.PIPE, > + check=False) > if callgrind.returncode: > sys.exit(callgrind.stderr.decode("utf-8")) > > @@ -102,7 +111,8 @@ def main(): > callgrind_annotate = subprocess.run( > ["callgrind_annotate", data_path, "--tree=caller"], > stdout=output, > - stderr=subprocess.PIPE) > + stderr=subprocess.PIPE, > + check=False) > if callgrind_annotate.returncode: > sys.exit(callgrind_annotate.stderr.decode("utf-8")) > > @@ -120,25 +130,28 @@ def main(): > total_instructions = int(total_instructions.replace(',', '')) > > # Line number with the JIT self number of instructions > - JIT_self_instructions_line_number = get_JIT_line(callgrind_data) > + jit_self_instructions_line_number = get_jit_line(callgrind_data) > # Get the JIT self number of instructions > - JIT_self_instructions_line_data = \ > - callgrind_data[JIT_self_instructions_line_number] > - JIT_self_instructions = JIT_self_instructions_line_ > data.split()[0] > - JIT_self_instructions = int(JIT_self_instructions.replace(',', > '')) > + jit_self_instructions_line_data = \ > + callgrind_data[jit_self_instructions_line_number] > + jit_self_instructions = jit_self_instructions_line_ > data.split()[0] > + jit_self_instructions = int(jit_self_instructions.replace(',', > '')) > > # Line number with the JIT self + inclusive number of instructions > - # It's the line above the first JIT call when running with > --tree=caller > - JIT_total_instructions_line_number = JIT_self_instructions_line_ > number-1 > + # It's the line above the first JIT call when running with > + # --tree=caller > + jit_total_instructions_line_number = \ > + jit_self_instructions_line_number-1 > # Get the JIT self + inclusive number of instructions > - JIT_total_instructions_line_data = \ > - callgrind_data[JIT_total_instructions_line_number] > - JIT_total_instructions = JIT_total_instructions_line_ > data.split()[0] > - JIT_total_instructions = int(JIT_total_instructions.replace(',', > '')) > + jit_total_instructions_line_data = \ > + callgrind_data[jit_total_instructions_line_number] > + jit_total_instructions = jit_total_instructions_line_ > data.split()[0] > + jit_total_instructions = int(jit_total_instructions.replace(',', > '')) > > # Calculate number of instructions in helpers and code generation > - helpers_instructions = JIT_total_instructions-JIT_ > self_instructions > - code_generation_instructions = total_instructions-JIT_total_ > instructions > + helpers_instructions = jit_total_instructions-jit_ > self_instructions > + code_generation_instructions = \ > + total_instructions-jit_total_instructions > > # Print results (Insert commas in large numbers) > # Print total number of instructions > @@ -149,12 +162,12 @@ def main(): > print('{:<20}{:>20}\t{:>6.3f}%'. > format("Code Generation:", > format(code_generation_instructions, ","), > - (code_generation_instructions / total_instructions) > * 100)) > - # Print JIT instructions and percentage > + (code_generation_instructions/ > total_instructions)*100)) > + # Print jit instructions and percentage > print('{:<20}{:>20}\t{:>6.3f}%'. > - format("JIT Execution:", > - format(JIT_self_instructions, ","), > - (JIT_self_instructions / total_instructions) * 100)) > + format("jit Execution:", > + format(jit_self_instructions, ","), > + (jit_self_instructions / total_instructions) * 100)) > # Print helpers instructions and percentage > print('{:<20}{:>20}\t{:>6.3f}%'. > format("Helpers:", > -- > 2.17.1 > >