Nikos Nikoleris has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/13598
Change subject: config: Make cpu clusters a parameter for ruby configuration
......................................................................
config: Make cpu clusters a parameter for ruby configuration
This change adds another parameter, the cpu_clusters, to the
create_system() ruby method that creates the memory system. This is
necessary as the memory system create caches private to the core and
it also needs to use the cores' clocks.
Change-Id: I384bbb3dfbbcda8cab4896b9550a3d21b0b2ff17
Signed-off-by: Nikos Nikoleris <[email protected]>
---
M configs/ruby/GPU_RfO.py
M configs/ruby/GPU_VIPER.py
M configs/ruby/GPU_VIPER_Baseline.py
M configs/ruby/GPU_VIPER_Region.py
M configs/ruby/Garnet_standalone.py
M configs/ruby/MESI_Three_Level.py
M configs/ruby/MESI_Two_Level.py
M configs/ruby/MI_example.py
M configs/ruby/MOESI_AMD_Base.py
M configs/ruby/MOESI_CMP_directory.py
M configs/ruby/MOESI_CMP_token.py
M configs/ruby/MOESI_hammer.py
M configs/ruby/Ruby.py
13 files changed, 96 insertions(+), 139 deletions(-)
diff --git a/configs/ruby/GPU_RfO.py b/configs/ruby/GPU_RfO.py
index 895c693..37fba7f 100644
--- a/configs/ruby/GPU_RfO.py
+++ b/configs/ruby/GPU_RfO.py
@@ -425,8 +425,8 @@
parser.add_option("--tcc-dir-factor", type='int', default=4,
help="TCCdir size = factor *(TCPs + TCC)")
-def create_system(options, full_system, system, dma_devices, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_cluster, dma_devices,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'GPU_RfO':
panic("This script requires the GPU_RfO protocol to be built.")
diff --git a/configs/ruby/GPU_VIPER.py b/configs/ruby/GPU_VIPER.py
index 87c84b8..e167e34 100644
--- a/configs/ruby/GPU_VIPER.py
+++ b/configs/ruby/GPU_VIPER.py
@@ -388,8 +388,8 @@
parser.add_option("--noL1", action = "store_true", default = False,
help = "bypassL1")
-def create_system(options, full_system, system, dma_devices, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_cluster, dma_devices,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'GPU_VIPER':
panic("This script requires the GPU_VIPER protocol to be built.")
diff --git a/configs/ruby/GPU_VIPER_Baseline.py
b/configs/ruby/GPU_VIPER_Baseline.py
index 19005ea..f3d49a7 100644
--- a/configs/ruby/GPU_VIPER_Baseline.py
+++ b/configs/ruby/GPU_VIPER_Baseline.py
@@ -371,8 +371,8 @@
parser.add_option("--noL2", action = "store_true", default = False,
help = "bypassL2")
-def create_system(options, full_system, system, dma_devices, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_cluster, dma_devices,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'GPU_VIPER_Baseline':
panic("This script requires the" \
"GPU_VIPER_Baseline protocol to be built.")
diff --git a/configs/ruby/GPU_VIPER_Region.py
b/configs/ruby/GPU_VIPER_Region.py
index 98a054e..51780cb 100644
--- a/configs/ruby/GPU_VIPER_Region.py
+++ b/configs/ruby/GPU_VIPER_Region.py
@@ -440,8 +440,8 @@
action="store_true", default=False)
parser.add_option("--use-L3-on-WT", action="store_true", default=False)
-def create_system(options, full_system, system, dma_devices, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_cluster, dma_devices,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'GPU_VIPER_Region':
panic("This script requires the GPU_VIPER_Region protocol to be
built.")
diff --git a/configs/ruby/Garnet_standalone.py
b/configs/ruby/Garnet_standalone.py
index a70780b..b165830 100644
--- a/configs/ruby/Garnet_standalone.py
+++ b/configs/ruby/Garnet_standalone.py
@@ -42,8 +42,8 @@
def define_options(parser):
return
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_cluster, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'Garnet_standalone':
panic("This script requires Garnet_standalone protocol to be
built.")
diff --git a/configs/ruby/MESI_Three_Level.py
b/configs/ruby/MESI_Three_Level.py
index f38b7cf..1c6a2e3 100644
--- a/configs/ruby/MESI_Three_Level.py
+++ b/configs/ruby/MESI_Three_Level.py
@@ -49,8 +49,8 @@
caches private to clusters")
return
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MESI_Three_Level':
fatal("This script requires the MESI_Three_Level protocol to be\
@@ -69,22 +69,19 @@
l2_cntrl_nodes = []
dma_cntrl_nodes = []
- assert (options.num_cpus % options.num_clusters == 0)
- num_cpus_per_cluster = options.num_cpus / options.num_clusters
+ num_clusters = len(cpu_clusters)
+ num_cpus_per_cluster = options.num_cpus / num_clusters
- assert (options.num_l2caches % options.num_clusters == 0)
- num_l2caches_per_cluster = options.num_l2caches / options.num_clusters
+ assert (options.num_l2caches % num_clusters == 0)
+ num_l2caches_per_cluster = options.num_l2caches / num_clusters
l2_bits = int(math.log(num_l2caches_per_cluster, 2))
block_size_bits = int(math.log(options.cacheline_size, 2))
l2_index_start = block_size_bits + l2_bits
- #
- # Must create the individual controllers before the network to ensure
the
- # controller constructors are called before the network constructor
- #
- for i in xrange(options.num_clusters):
- for j in xrange(num_cpus_per_cluster):
+ for i, cpu_cluster in enumerate(cpu_clusters):
+ for j, cpu in enumerate(cpu_cluster):
+ cpu_id = i * num_cpus_per_cluster + j
#
# First create the Ruby objects associated with this cpu
#
@@ -96,26 +93,14 @@
start_index_bit = block_size_bits,
replacement_policy = LRUReplacementPolicy())
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
l0_cntrl = L0Cache_Controller(
- version = i * num_cpus_per_cluster + j, Icache =
l0i_cache,
+ version = cpu_id, Icache = l0i_cache,
Dcache = l0d_cache, send_evictions =
send_evicts(options),
- clk_domain = clk_domain, ruby_system = ruby_system)
+ clk_domain = cpu.clk_domain, ruby_system = ruby_system)
- cpu_seq = RubySequencer(version = i * num_cpus_per_cluster + j,
+ cpu_seq = RubySequencer(version = cpu_id,
icache = l0i_cache,
- clk_domain = clk_domain,
+ clk_domain = cpu.clk_domain,
dcache = l0d_cache,
ruby_system = ruby_system)
@@ -127,14 +112,12 @@
is_icache = False)
l1_cntrl = L1Cache_Controller(
- version = i * num_cpus_per_cluster + j,
+ version = cpu_id,
cache = l1_cache, l2_select_num_bits = l2_bits,
cluster_id = i, ruby_system = ruby_system)
- exec("ruby_system.l0_cntrl%d = l0_cntrl"
- % ( i * num_cpus_per_cluster + j))
- exec("ruby_system.l1_cntrl%d = l1_cntrl"
- % ( i * num_cpus_per_cluster + j))
+ exec("ruby_system.l0_cntrl%d = l0_cntrl" % cpu_id)
+ exec("ruby_system.l1_cntrl%d = l1_cntrl" % cpu_id)
#
# Add controllers and sequencers to the appropriate lists
diff --git a/configs/ruby/MESI_Two_Level.py b/configs/ruby/MESI_Two_Level.py
index 52976e6..6cc7088 100644
--- a/configs/ruby/MESI_Two_Level.py
+++ b/configs/ruby/MESI_Two_Level.py
@@ -43,8 +43,8 @@
def define_options(parser):
return
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MESI_Two_Level':
fatal("This script requires the MESI_Two_Level protocol to be
built.")
@@ -67,7 +67,10 @@
l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2))
- for i in xrange(options.num_cpus):
+ cpu_list = []
+ for cpu_cluster in cpu_clusters:
+ cpu_list += cpu_cluster.cpus
+ for i, cpu in enumerate(cpu_list):
#
# First create the Ruby objects associated with this cpu
#
@@ -82,30 +85,19 @@
prefetcher = RubyPrefetcher.Prefetcher()
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
l1_cntrl = L1Cache_Controller(version = i, L1Icache = l1i_cache,
L1Dcache = l1d_cache,
l2_select_num_bits = l2_bits,
send_evictions =
send_evicts(options),
prefetcher = prefetcher,
ruby_system = ruby_system,
- clk_domain = clk_domain,
+ clk_domain = cpu.clk_domain,
transitions_per_cycle =
options.ports,
enable_prefetch = False)
cpu_seq = RubySequencer(version = i, icache = l1i_cache,
- dcache = l1d_cache, clk_domain =
clk_domain,
+ dcache = l1d_cache,
+ clk_domain = cpu.clk_domain,
ruby_system = ruby_system)
diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py
index 222d084..c21ffe0 100644
--- a/configs/ruby/MI_example.py
+++ b/configs/ruby/MI_example.py
@@ -42,8 +42,8 @@
def define_options(parser):
return
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MI_example':
panic("This script requires the MI_example protocol to be built.")
@@ -64,38 +64,25 @@
#
block_size_bits = int(math.log(options.cacheline_size, 2))
- for i in xrange(options.num_cpus):
- #
- # First create the Ruby objects associated with this cpu
- # Only one cache exists for this protocol, so by default use the
L1D
- # config parameters.
+ cpu_list = []
+ for cpu_cluster in cpu_clusters:
+ cpu_list += cpu_cluster.cpus
+ for i, cpu in enumerate(cpu_list):
#
cache = L1Cache(size = options.l1d_size,
assoc = options.l1d_assoc,
start_index_bit = block_size_bits)
-
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
# Only one unified L1 cache exists. Can cache instructions and
data.
l1_cntrl = L1Cache_Controller(version=i, cacheMemory=cache,
send_evictions=send_evicts(options),
transitions_per_cycle=options.ports,
- clk_domain=clk_domain,
+ clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
cpu_seq = RubySequencer(version=i, icache=cache, dcache=cache,
- clk_domain=clk_domain,
ruby_system=ruby_system)
+ clk_domain=cpu.clk_domain,
+ ruby_system=ruby_system)
l1_cntrl.sequencer = cpu_seq
exec("ruby_system.l1_cntrl%d = l1_cntrl" % i)
diff --git a/configs/ruby/MOESI_AMD_Base.py b/configs/ruby/MOESI_AMD_Base.py
index 407f2e8..27cd0cd 100644
--- a/configs/ruby/MOESI_AMD_Base.py
+++ b/configs/ruby/MOESI_AMD_Base.py
@@ -207,8 +207,8 @@
parser.add_option("--num-tbes", type="int", default=256)
parser.add_option("--l2-latency", type="int", default=50) # load to use
-def create_system(options, full_system, system, dma_devices, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_devices,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_AMD_Base':
panic("This script requires the MOESI_AMD_Base protocol.")
diff --git a/configs/ruby/MOESI_CMP_directory.py
b/configs/ruby/MOESI_CMP_directory.py
index 3fef48b..cad5dd4 100644
--- a/configs/ruby/MOESI_CMP_directory.py
+++ b/configs/ruby/MOESI_CMP_directory.py
@@ -43,8 +43,8 @@
def define_options(parser):
return
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_directory':
panic("This script requires the MOESI_CMP_directory protocol to be
built.")
@@ -67,7 +67,10 @@
l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2))
- for i in xrange(options.num_cpus):
+ cpu_list = []
+ for cpu_cluster in cpu_clusters:
+ cpu_list += cpu_cluster.cpus
+ for i, cpu in enumerate(cpu_list):
#
# First create the Ruby objects associated with this cpu
#
@@ -80,28 +83,16 @@
start_index_bit = block_size_bits,
is_icache = False)
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache,
l2_select_num_bits=l2_bits,
send_evictions=send_evicts(options),
transitions_per_cycle=options.ports,
- clk_domain=clk_domain,
+ clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
cpu_seq = RubySequencer(version=i, icache=l1i_cache,
- dcache=l1d_cache, clk_domain=clk_domain,
+ dcache=l1d_cache,
clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
l1_cntrl.sequencer = cpu_seq
diff --git a/configs/ruby/MOESI_CMP_token.py
b/configs/ruby/MOESI_CMP_token.py
index 94a518b..b8ab2b4 100644
--- a/configs/ruby/MOESI_CMP_token.py
+++ b/configs/ruby/MOESI_CMP_token.py
@@ -50,8 +50,8 @@
parser.add_option("--allow-atomic-migration", action="store_true",
help="allow migratory sharing for atomic only accessed blocks")
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_token':
panic("This script requires the MOESI_CMP_token protocol to be
built.")
@@ -80,7 +80,10 @@
l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2))
- for i in xrange(options.num_cpus):
+ cpu_list = []
+ for cpu_cluster in cpu_clusters:
+ cpu_list += cpu_cluster.cpus
+ for i, cpu in enumerate(cpu_list):
#
# First create the Ruby objects associated with this cpu
#
@@ -91,18 +94,6 @@
assoc = options.l1d_assoc,
start_index_bit = block_size_bits)
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache,
l2_select_num_bits=l2_bits,
@@ -116,11 +107,11 @@
options.allow_atomic_migration,
send_evictions=send_evicts(options),
transitions_per_cycle=options.ports,
- clk_domain=clk_domain,
+ clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
cpu_seq = RubySequencer(version=i, icache=l1i_cache,
- dcache=l1d_cache, clk_domain=clk_domain,
+ dcache=l1d_cache,
clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
l1_cntrl.sequencer = cpu_seq
diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py
index 7c31ca2..c74d50f 100644
--- a/configs/ruby/MOESI_hammer.py
+++ b/configs/ruby/MOESI_hammer.py
@@ -52,8 +52,8 @@
parser.add_option("--dir-on", action="store_true",
help="Hammer: enable Full-bit Directory")
-def create_system(options, full_system, system, dma_ports, bootmem,
- ruby_system):
+def create_system(options, full_system, system, cpu_clusters, dma_ports,
+ bootmem, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be
built.")
@@ -74,7 +74,10 @@
#
block_size_bits = int(math.log(options.cacheline_size, 2))
- for i in xrange(options.num_cpus):
+ cpu_list = []
+ for cpu_cluster in cpu_clusters:
+ cpu_list += cpu_cluster.cpus
+ for i, cpu in enumerate(cpu_list):
#
# First create the Ruby objects associated with this cpu
#
@@ -89,29 +92,17 @@
assoc = options.l2_assoc,
start_index_bit = block_size_bits)
- # the ruby random tester reuses num_cpus to specify the
- # number of cpu ports connected to the tester object, which
- # is stored in system.cpu. because there is only ever one
- # tester object, num_cpus is not necessarily equal to the
- # size of system.cpu; therefore if len(system.cpu) == 1
- # we use system.cpu[0] to set the clk_domain, thereby ensuring
- # we don't index off the end of the cpu list.
- if len(system.cpu) == 1:
- clk_domain = system.cpu[0].clk_domain
- else:
- clk_domain = system.cpu[i].clk_domain
-
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache, L2cache=l2_cache,
no_mig_atomic=not \
options.allow_atomic_migration,
send_evictions=send_evicts(options),
transitions_per_cycle=options.ports,
- clk_domain=clk_domain,
+ clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
cpu_seq = RubySequencer(version=i, icache=l1i_cache,
- dcache=l1d_cache,clk_domain=clk_domain,
+ dcache=l1d_cache,clk_domain=cpu.clk_domain,
ruby_system=ruby_system)
l1_cntrl.sequencer = cpu_seq
diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py
index 2fb1740..efb7c54 100644
--- a/configs/ruby/Ruby.py
+++ b/configs/ruby/Ruby.py
@@ -146,8 +146,8 @@
topology = eval("Topo.%s(controllers)" % options.topology)
return topology
-def create_system(options, full_system, system, piobus = None, dma_ports =
[],
- bootmem=None):
+def create_system(options, full_system, system, piobus = None,
+ dma_ports = [], bootmem=None, cpu_clusters=None):
system.ruby = RubySystem()
ruby = system.ruby
@@ -160,9 +160,31 @@
protocol = buildEnv['PROTOCOL']
exec "import %s" % protocol
try:
+ if cpu_clusters is None:
+ num_clusters = getattr(options, "num-clusters", 1)
+
+ assert (options.num_cpus % num_clusters == 0)
+ num_cpus_per_cluster = options.num_cpus / num_clusters
+
+ cpu_clusters = []
+ for i in range(0, num_clusters):
+ class CpuCluster(object):
+ pass
+
+ cpu_cluster = CpuCluster()
+ cpu_cluster.cpus = []
+ for j in range(0, num_cpus_per_cluster):
+ if len(system.cpu) == 1:
+ cpu = system.cpu[0]
+ else:
+ cpu = system.cpu[i * num_cpus_per_cluster + j]
+ cpu_cluster.cpus.append(cpu)
+ cpu_clusters.append(cpu_cluster)
+ assert (options.num_cpus % len(cpu_clusters) == 0)
+
(cpu_sequencers, dir_cntrls, topology) = \
- eval("%s.create_system(options, full_system, system,
dma_ports,\
- bootmem, ruby)"
+ eval("%s.create_system(options, full_system, system, \
+ cpu_clusters, dma_ports, bootmem,
ruby)"
% protocol)
except:
print("Error: could not create sytem for ruby protocol %s" %
protocol)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/13598
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I384bbb3dfbbcda8cab4896b9550a3d21b0b2ff17
Gerrit-Change-Number: 13598
Gerrit-PatchSet: 1
Gerrit-Owner: Nikos Nikoleris <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev