From 439b68a21e5122df2e6d1b9aad7ac46af619cc75 Mon Sep 17 00:00:00 2001 From: Pau Cabre Date: Wed, 7 Nov 2018 23:22:05 +0100 Subject: configs: Added an option for choosing branch predictor type Added the parameter "--bp-type" to set the branch predictor type Added the parameter "--list-bp-types" to list all the available branch predictor types Change-Id: Ia6aae90c784aef359b6d8233c8383cd7a871aca1 Signed-off-by: Pau Cabre Reviewed-on: https://gem5-review.googlesource.com/c/14015 Reviewed-by: Andreas Sandberg Reviewed-by: Jason Lowe-Power Maintainer: Andreas Sandberg --- configs/common/BPConfig.py | 87 +++++++++++++++++++++++++++++++++++++++++ configs/common/Options.py | 14 +++++++ configs/common/Simulation.py | 4 ++ configs/common/cores/arm/HPI.py | 2 +- configs/example/fs.py | 4 ++ configs/example/se.py | 5 +++ src/cpu/pred/BranchPredictor.py | 3 +- 7 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 configs/common/BPConfig.py diff --git a/configs/common/BPConfig.py b/configs/common/BPConfig.py new file mode 100644 index 000000000..5e5b92f8a --- /dev/null +++ b/configs/common/BPConfig.py @@ -0,0 +1,87 @@ +# Copyright (c) 2018 Metempsy Technology Consulting +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Pau Cabre + +# This file is a copy of MemConfig.py / CpuConfig.py, but modified to +# hanle branch predictors instead of memory controllers / CPUs + +from __future__ import print_function + +from m5 import fatal +import m5.objects +import inspect +import sys +from textwrap import TextWrapper + +# Dictionary of mapping names of real branch predictor models to classes. +_bp_classes = {} + + +def is_bp_class(cls): + """Determine if a class is a branch predictor that can be instantiated""" + + # We can't use the normal inspect.isclass because the ParamFactory + # and ProxyFactory classes have a tendency to confuse it. + try: + return issubclass(cls, m5.objects.BranchPredictor) and \ + not cls.abstract + except (TypeError, AttributeError): + return False + +def get(name): + """Get a BP class from a user provided class name or alias.""" + + try: + bp_class = _bp_classes[name] + return bp_class + except KeyError: + print("%s is not a valid BP model." % (name,)) + sys.exit(1) + +def print_bp_list(): + """Print a list of available BP classes.""" + + print("Available BranchPredictor classes:") + doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") + for name, cls in _bp_classes.items(): + print("\t%s" % name) + + # Try to extract the class documentation from the class help + # string. + doc = inspect.getdoc(cls) + if doc: + for line in doc_wrapper.wrap(doc): + print(line) + +def bp_names(): + """Return a list of valid Branch Predictor names.""" + return _bp_classes.keys() + +# Add all BPs in the object hierarchy. +for name, cls in inspect.getmembers(m5.objects, is_bp_class): + _bp_classes[name] = cls + diff --git a/configs/common/Options.py b/configs/common/Options.py index c36dc384e..536da44f0 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -44,6 +44,7 @@ from m5.objects import * from common.Benchmarks import * from common import CpuConfig +from common import BPConfig from common import MemConfig from common import PlatformConfig @@ -51,6 +52,10 @@ def _listCpuTypes(option, opt, value, parser): CpuConfig.print_cpu_list() sys.exit(0) +def _listBPTypes(option, opt, value, parser): + BPConfig.print_bp_list() + sys.exit(0) + def _listMemTypes(option, opt, value, parser): MemConfig.print_mem_list() sys.exit(0) @@ -146,6 +151,15 @@ def addCommonOptions(parser): parser.add_option("--cpu-type", type="choice", default="AtomicSimpleCPU", choices=CpuConfig.cpu_names(), help = "type of cpu to run with") + parser.add_option("--list-bp-types", + action="callback", callback=_listBPTypes, + help="List available branch predictor types") + parser.add_option("--bp-type", type="choice", default=None, + choices=BPConfig.bp_names(), + help = """ + type of branch predictor to run with + (if not set, use the default branch predictor of + the selected CPU)""") parser.add_option("--checker", action="store_true"); parser.add_option("--cpu-clock", action="store", type="string", default='2GHz', diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 23a778397..19bd962e8 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -46,6 +46,7 @@ from os import getcwd from os.path import join as joinpath from common import CpuConfig +from common import BPConfig from common import MemConfig import m5 @@ -478,6 +479,9 @@ def run(options, root, testsys, cpu_class): # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() + if options.bp_type: + bpClass = BPConfig.get(options.bp_type) + switch_cpus[i].branchPred = bpClass() # If elastic tracing is enabled attach the elastic trace probe # to the switch CPUs diff --git a/configs/common/cores/arm/HPI.py b/configs/common/cores/arm/HPI.py index a6f77af7f..2efb7dfec 100644 --- a/configs/common/cores/arm/HPI.py +++ b/configs/common/cores/arm/HPI.py @@ -1443,7 +1443,7 @@ class HPI(MinorCPU): enableIdling = True - branchPred = HPI_BP(numThreads = Parent.numThreads) + branchPred = HPI_BP() itb = HPI_ITB() dtb = HPI_DTB() diff --git a/configs/example/fs.py b/configs/example/fs.py index 3997ed76c..3fdf151c9 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -63,6 +63,7 @@ from common import Simulation from common import CacheConfig from common import MemConfig from common import CpuConfig +from common import BPConfig from common.Caches import * from common import Options @@ -199,6 +200,9 @@ def build_test_system(np): test_sys.cpu[i].addSimPointProbe(options.simpoint_interval) if options.checker: test_sys.cpu[i].addCheckerCpu() + if options.bp_type: + bpClass = BPConfig.get(options.bp_type) + test_sys.cpu[i].branchPred = bpClass() test_sys.cpu[i].createThreads() # If elastic tracing is enabled when not restoring from checkpoint and diff --git a/configs/example/se.py b/configs/example/se.py index f12d4a994..8403066f0 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -61,6 +61,7 @@ from common import Options from common import Simulation from common import CacheConfig from common import CpuConfig +from common import BPConfig from common import MemConfig from common.Caches import * from common.cpu2000 import * @@ -233,6 +234,10 @@ for i in xrange(np): if options.checker: system.cpu[i].addCheckerCpu() + if options.bp_type: + bpClass = BPConfig.get(options.bp_type) + system.cpu[i].branchPred = bpClass() + system.cpu[i].createThreads() if options.ruby: diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py index 9f3516597..1eeecde95 100644 --- a/src/cpu/pred/BranchPredictor.py +++ b/src/cpu/pred/BranchPredictor.py @@ -29,6 +29,7 @@ from m5.SimObject import SimObject from m5.params import * +from m5.proxy import * class BranchPredictor(SimObject): type = 'BranchPredictor' @@ -36,7 +37,7 @@ class BranchPredictor(SimObject): cxx_header = "cpu/pred/bpred_unit.hh" abstract = True - numThreads = Param.Unsigned(1, "Number of threads") + numThreads = Param.Unsigned(Parent.numThreads, "Number of threads") BTBEntries = Param.Unsigned(4096, "Number of BTB entries") BTBTagSize = Param.Unsigned(16, "Size of the BTB tags, in bits") RASSize = Param.Unsigned(16, "RAS size") -- cgit v1.2.3