sweep.py (12564:2778478ca882) | sweep.py (12814:074f6240ff4c) |
---|---|
1# Copyright (c) 2014-2015 ARM Limited | 1# Copyright (c) 2014-2015, 2018 ARM Limited |
2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 22 unchanged lines hidden (view full) --- 32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35# 36# Authors: Andreas Hansson 37 38from __future__ import print_function 39 | 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 22 unchanged lines hidden (view full) --- 32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35# 36# Authors: Andreas Hansson 37 38from __future__ import print_function 39 |
40import math |
|
40import optparse 41 42import m5 43from m5.objects import * 44from m5.util import addToPath 45from m5.stats import periodicStatDump 46 47addToPath('../') 48 49from common import MemConfig 50 51# this script is helpful to sweep the efficiency of a specific memory 52# controller configuration, by varying the number of banks accessed, 53# and the sequential stride size (how many bytes per activate), and 54# observe what bus utilisation (bandwidth) is achieved 55 56parser = optparse.OptionParser() 57 | 41import optparse 42 43import m5 44from m5.objects import * 45from m5.util import addToPath 46from m5.stats import periodicStatDump 47 48addToPath('../') 49 50from common import MemConfig 51 52# this script is helpful to sweep the efficiency of a specific memory 53# controller configuration, by varying the number of banks accessed, 54# and the sequential stride size (how many bytes per activate), and 55# observe what bus utilisation (bandwidth) is achieved 56 57parser = optparse.OptionParser() 58 |
59dram_generators = { 60 "DRAM" : lambda x: x.createDram, 61 "DRAM_ROTATE" : lambda x: x.createDramRot, 62} 63 |
|
58# Use a single-channel DDR3-1600 x64 (8x8 topology) by default 59parser.add_option("--mem-type", type="choice", default="DDR3_1600_8x8", 60 choices=MemConfig.mem_names(), 61 help = "type of memory to use") 62 63parser.add_option("--mem-ranks", "-r", type="int", default=1, 64 help = "Number of ranks to iterate across") 65 66parser.add_option("--rd_perc", type="int", default=100, 67 help = "Percentage of read commands") 68 69parser.add_option("--mode", type="choice", default="DRAM", | 64# Use a single-channel DDR3-1600 x64 (8x8 topology) by default 65parser.add_option("--mem-type", type="choice", default="DDR3_1600_8x8", 66 choices=MemConfig.mem_names(), 67 help = "type of memory to use") 68 69parser.add_option("--mem-ranks", "-r", type="int", default=1, 70 help = "Number of ranks to iterate across") 71 72parser.add_option("--rd_perc", type="int", default=100, 73 help = "Percentage of read commands") 74 75parser.add_option("--mode", type="choice", default="DRAM", |
70 choices=["DRAM", "DRAM_ROTATE"], | 76 choices=dram_generators.keys(), |
71 help = "DRAM: Random traffic; \ 72 DRAM_ROTATE: Traffic rotating across banks and ranks") 73 74parser.add_option("--addr_map", type="int", default=1, 75 help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo") 76 77(options, args) = parser.parse_args() 78 --- 43 unchanged lines hidden (view full) --- 122 system.mem_ctrls[0].addr_mapping = "RoRaBaCoCh" 123else: 124 fatal("Did not specify a valid address map argument") 125 126# stay in each state for 0.25 ms, long enough to warm things up, and 127# short enough to avoid hitting a refresh 128period = 250000000 129 | 77 help = "DRAM: Random traffic; \ 78 DRAM_ROTATE: Traffic rotating across banks and ranks") 79 80parser.add_option("--addr_map", type="int", default=1, 81 help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo") 82 83(options, args) = parser.parse_args() 84 --- 43 unchanged lines hidden (view full) --- 128 system.mem_ctrls[0].addr_mapping = "RoRaBaCoCh" 129else: 130 fatal("Did not specify a valid address map argument") 131 132# stay in each state for 0.25 ms, long enough to warm things up, and 133# short enough to avoid hitting a refresh 134period = 250000000 135 |
130# this is where we go off piste, and print the traffic generator 131# configuration that we will later use, crazy but it works 132cfg_file_name = "configs/dram/sweep.cfg" 133cfg_file = open(cfg_file_name, 'w') 134 | |
135# stay in each state as long as the dump/reset period, use the entire 136# range, issue transactions of the right DRAM burst size, and match 137# the DRAM maximum bandwidth to ensure that it is saturated 138 139# get the number of banks 140nbr_banks = system.mem_ctrls[0].banks_per_rank.value 141 142# determine the burst length in bytes --- 11 unchanged lines hidden (view full) --- 154 155# assume we start at 0 156max_addr = mem_range.end 157 158# use min of the page size and 512 bytes as that should be more than 159# enough 160max_stride = min(512, page_size) 161 | 136# stay in each state as long as the dump/reset period, use the entire 137# range, issue transactions of the right DRAM burst size, and match 138# the DRAM maximum bandwidth to ensure that it is saturated 139 140# get the number of banks 141nbr_banks = system.mem_ctrls[0].banks_per_rank.value 142 143# determine the burst length in bytes --- 11 unchanged lines hidden (view full) --- 155 156# assume we start at 0 157max_addr = mem_range.end 158 159# use min of the page size and 512 bytes as that should be more than 160# enough 161max_stride = min(512, page_size) 162 |
162# now we create the state by iterating over the stride size from burst 163# size to the max stride, and from using only a single bank up to the 164# number of banks available 165nxt_state = 0 166for bank in range(1, nbr_banks + 1): 167 for stride_size in range(burst_size, max_stride + 1, burst_size): 168 cfg_file.write("STATE %d %d %s %d 0 %d %d " 169 "%d %d %d %d %d %d %d %d %d\n" % 170 (nxt_state, period, options.mode, options.rd_perc, 171 max_addr, burst_size, itt, itt, 0, stride_size, 172 page_size, nbr_banks, bank, options.addr_map, 173 options.mem_ranks)) 174 nxt_state = nxt_state + 1 175 176cfg_file.write("INIT 0\n") 177 178# go through the states one by one 179for state in range(1, nxt_state): 180 cfg_file.write("TRANSITION %d %d 1\n" % (state - 1, state)) 181 182cfg_file.write("TRANSITION %d %d 1\n" % (nxt_state - 1, nxt_state - 1)) 183 184cfg_file.close() 185 | |
186# create a traffic generator, and point it to the file we just created | 163# create a traffic generator, and point it to the file we just created |
187system.tgen = TrafficGen(config_file = cfg_file_name) | 164system.tgen = PyTrafficGen() |
188 189# add a communication monitor 190system.monitor = CommMonitor() 191 192# connect the traffic generator to the bus via a communication monitor 193system.tgen.port = system.monitor.slave 194system.monitor.master = system.membus.slave 195 196# connect the system port even if it is not used in this example 197system.system_port = system.membus.slave 198 199# every period, dump and reset all stats 200periodicStatDump(period) 201 202# run Forrest, run! 203root = Root(full_system = False, system = system) 204root.system.mem_mode = 'timing' 205 206m5.instantiate() | 165 166# add a communication monitor 167system.monitor = CommMonitor() 168 169# connect the traffic generator to the bus via a communication monitor 170system.tgen.port = system.monitor.slave 171system.monitor.master = system.membus.slave 172 173# connect the system port even if it is not used in this example 174system.system_port = system.membus.slave 175 176# every period, dump and reset all stats 177periodicStatDump(period) 178 179# run Forrest, run! 180root = Root(full_system = False, system = system) 181root.system.mem_mode = 'timing' 182 183m5.instantiate() |
207m5.simulate(nxt_state * period) | |
208 | 184 |
185def trace(): 186 generator = dram_generators[options.mode](system.tgen) 187 for bank in range(1, nbr_banks + 1): 188 for stride_size in range(burst_size, max_stride + 1, burst_size): 189 num_seq_pkts = int(math.ceil(float(stride_size) / burst_size)) 190 yield generator(period, 191 0, max_addr, burst_size, int(itt), int(itt), 192 options.rd_perc, 0, 193 num_seq_pkts, page_size, nbr_banks, bank, 194 options.addr_map, options.mem_ranks) 195 yield system.tgen.createExit(0) 196 197system.tgen.start(trace()) 198 199m5.simulate() 200 |
|
209print("DRAM sweep with burst: %d, banks: %d, max stride: %d" % 210 (burst_size, nbr_banks, max_stride)) | 201print("DRAM sweep with burst: %d, banks: %d, max stride: %d" % 202 (burst_size, nbr_banks, max_stride)) |