aboutsummaryrefslogtreecommitdiffstats
path: root/gen
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-04-23 17:28:12 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2013-04-23 17:28:12 -0400
commit2ceaa6c607ef85bde4f14017634d9d1621efca29 (patch)
treec85e755e59907a48ff762fd56473449f33c23894 /gen
parenta0e4b9fe9d7fab9a50a626cfeda3c614a9a6af5d (diff)
parent7545402506aa76261e18d85af585ff0ac1cf05c1 (diff)
Merge branch 'master' into wip-color-mc
Conflicts: gen/generator.py parse/sched.py parse_exps.py
Diffstat (limited to 'gen')
-rw-r--r--gen/edf_generators.py24
-rw-r--r--gen/generator.py24
-rw-r--r--gen/mc_generators.py82
3 files changed, 95 insertions, 35 deletions
diff --git a/gen/edf_generators.py b/gen/edf_generators.py
index 3f05b76..a722c21 100644
--- a/gen/edf_generators.py
+++ b/gen/edf_generators.py
@@ -16,10 +16,10 @@ class EdfGenerator(gen.Generator):
16 16
17 def __make_options(self): 17 def __make_options(self):
18 '''Return generic EDF options.''' 18 '''Return generic EDF options.'''
19 return [gen.Generator._dist_option('utils', ['uni-medium'], 19 return [gen.Generator._dist_option('utils', 'uni-medium',
20 gen.NAMED_UTILIZATIONS, 20 gen.NAMED_UTILIZATIONS,
21 'Task utilization distributions.'), 21 'Task utilization distributions.'),
22 gen.Generator._dist_option('periods', ['harmonic'], 22 gen.Generator._dist_option('periods', 'harmonic',
23 gen.NAMED_PERIODS, 23 gen.NAMED_PERIODS,
24 'Task period distributions.')] 24 'Task period distributions.')]
25 25
@@ -50,10 +50,22 @@ class PartitionedGenerator(EdfGenerator):
50 templates + [TP_PART_TASK], options, params) 50 templates + [TP_PART_TASK], options, params)
51 51
52 def _customize(self, taskset, exp_params): 52 def _customize(self, taskset, exp_params):
53 start = 1 if exp_params['release_master'] else 0 53 cpus = exp_params['cpus']
54 # Random partition for now: could do a smart partitioning 54 start = 0
55 if exp_params['release_master']:
56 cpus -= 1
57 start = 1
58
59 # Partition using worst-fit for most even distribution
60 utils = [0]*cpus
61 tasks = [0]*cpus
55 for t in taskset: 62 for t in taskset:
56 t.cpu = random.randint(start, exp_params['cpus'] - 1) 63 t.cpu = utils.index(min(utils))
64 utils[t.cpu] += t.utilization()
65 tasks[t.cpu] += 1
66
67 # Increment by one so release master has no tasks
68 t.cpu += start
57 69
58class PedfGenerator(PartitionedGenerator): 70class PedfGenerator(PartitionedGenerator):
59 def __init__(self, params={}): 71 def __init__(self, params={}):
@@ -61,7 +73,7 @@ class PedfGenerator(PartitionedGenerator):
61 73
62class CedfGenerator(PartitionedGenerator): 74class CedfGenerator(PartitionedGenerator):
63 TP_CLUSTER = "plugins/C-EDF/cluster{$level}" 75 TP_CLUSTER = "plugins/C-EDF/cluster{$level}"
64 CLUSTER_OPTION = gen.GenOption('level', ['L2', 'L3', 'All'], ['L2'], 76 CLUSTER_OPTION = gen.GenOption('level', ['L2', 'L3', 'All'], 'L2',
65 'Cache clustering level.',) 77 'Cache clustering level.',)
66 78
67 def __init__(self, params={}): 79 def __init__(self, params={}):
diff --git a/gen/generator.py b/gen/generator.py
index 693e52f..bc86cfe 100644
--- a/gen/generator.py
+++ b/gen/generator.py
@@ -5,7 +5,7 @@ import schedcat.generator.tasks as tasks
5import shutil as sh 5import shutil as sh
6 6
7from Cheetah.Template import Template 7from Cheetah.Template import Template
8from common import get_config_option,num_cpus,recordtype 8from common import get_config_option,num_cpus,recordtype,log_once
9from config.config import DEFAULTS,PARAMS 9from config.config import DEFAULTS,PARAMS
10from gen.dp import DesignPointGenerator 10from gen.dp import DesignPointGenerator
11from parse.col_map import ColMapBuilder 11from parse.col_map import ColMapBuilder
@@ -69,11 +69,10 @@ class Generator(object):
69 else: 69 else:
70 self.cpus = num_cpus() 70 self.cpus = num_cpus()
71 try: 71 try:
72 config = get_config_option("RELEASE_MASTER") and True 72 rm_config = get_config_option("RELEASE_MASTER") and True
73 except: 73 except:
74 config = False 74 rm_config = False
75 self.release_master = list(set([False, config])) 75 self.release_master = list(set([False, bool(rm_config)]))
76
77 76
78 def __make_options(self, params): 77 def __make_options(self, params):
79 '''Return generic Litmus options.''' 78 '''Return generic Litmus options.'''
@@ -116,11 +115,11 @@ class Generator(object):
116 ts = tg.make_task_set(max_tasks = params['tasks'], max_util=max_util) 115 ts = tg.make_task_set(max_tasks = params['tasks'], max_util=max_util)
117 tries += 1 116 tries += 1
118 if len(ts) != params['tasks']: 117 if len(ts) != params['tasks']:
119 print(("Only created task set of size %d < %d for params %s. " + 118 log_once("only", ("Only created task set of size %d < %d for " +
120 "Switching to light utilization.") % 119 "params %s. Switching to light utilization.") %
121 (len(ts), params['tasks'], params)) 120 (len(ts), params['tasks'], params))
122 print("Switching to light util. This usually means the " + 121 log_once("light", "Switching to light util. This usually means " +
123 "utilization distribution is too agressive.") 122 "the utilization distribution is too agressive.")
124 return self._create_taskset(params, periods, NAMED_UTILIZATIONS['uni-light'], 123 return self._create_taskset(params, periods, NAMED_UTILIZATIONS['uni-light'],
125 max_util) 124 max_util)
126 return ts 125 return ts
@@ -156,7 +155,10 @@ class Generator(object):
156 '''Set default parameter values and check that values are valid.''' 155 '''Set default parameter values and check that values are valid.'''
157 for option in self.options: 156 for option in self.options:
158 if option.name not in params: 157 if option.name not in params:
159 params[option.name] = option.default 158 val = option.default
159 val = val if type(val) == type([]) else [val]
160
161 params[option.name] = val
160 else: 162 else:
161 option.hidden = True 163 option.hidden = True
162 params[option.name] = self._check_value(option.name, 164 params[option.name] = self._check_value(option.name,
diff --git a/gen/mc_generators.py b/gen/mc_generators.py
index 704bcc3..8f5bd84 100644
--- a/gen/mc_generators.py
+++ b/gen/mc_generators.py
@@ -1,8 +1,10 @@
1import gen.rv as rv 1import gen.rv as rv
2 2
3from color import get_cache_info,CacheInfo,BlockColorScheme,RandomColorScheme,EvilColorScheme 3from color import get_cache_info,CacheInfo,BlockColorScheme,RandomColorScheme,EvilColorScheme
4from common import try_get_config_option 4from common import try_get_config_option, log_once
5from gen.generator import GenOption,Generator,NAMED_UTILIZATIONS,NAMED_PERIODS 5from gen.generator import GenOption,Generator,NAMED_UTILIZATIONS,NAMED_PERIODS
6from parse.col_map import ColMap
7from parse.tuple_table import TupleTable
6 8
7 9
8NAMED_SHARES = { 10NAMED_SHARES = {
@@ -188,24 +190,24 @@ class McGenerator(Generator):
188 190
189 return self._create_taskset(params, periods, utils, max_util) 191 return self._create_taskset(params, periods, utils, max_util)
190 192
191 def _customize(self, task_system, params): 193 def _get_tasks(self, params):
192 pass 194 return {'lvla': self.__create_lvla_sched(params),
195 'lvlb': self.__create_lvlb_sched(params),
196 'lvlc': self.__create_lvlc_sched(params)}
193 197
194 def _create_exp(self, params): 198 def _create_exp(self, params):
195 # Ugly way of doing it 199 # Ugly way of doing it
196 self.shares = self._create_dist('shares', params['shares'], 200 self.shares = self._create_dist('shares', params['shares'],
197 NAMED_SHARES) 201 NAMED_SHARES)
198 202
199 tasks = {'lvla': self.__create_lvla_sched(params), 203 tasks = self._get_tasks(params)
200 'lvlb': self.__create_lvlb_sched(params),
201 'lvlc': self.__create_lvlc_sched(params)}
202 204
203 conf_options = {MC_OPT : 'y'} 205 conf_options = {MC_OPT : 'y'}
204 if params['timer_merging']: 206 if params['timer_merging']:
205 conf_options[TM_OPT] = 'y' 207 conf_options[TM_OPT] = 'y'
206 if params['redirect']: 208 if params['redirect']:
207 if not params['release_master']: 209 if not params['release_master']:
208 print("Forcing release master option to enable redirection.") 210 log_once("Forcing release master option to enable redirection.")
209 params['release_master'] = 'y' 211 params['release_master'] = 'y'
210 conf_options[RD_OPT] = 'y' 212 conf_options[RD_OPT] = 'y'
211 if params['slack_stealing']: 213 if params['slack_stealing']:
@@ -241,8 +243,11 @@ TP_TYPE = """#if $type != 'unmanaged'
241/proc/sys/litmus/color/preempt_cache{0} 243/proc/sys/litmus/color/preempt_cache{0}
242#end if""" 244#end if"""
243 245
246# Always add some pages
247TP_ADD = """/proc/sys/litmus/color/add_pages{1}"""
248
244# Use special spin for color tasks 249# Use special spin for color tasks
245TP_COLOR_BASE = """colorspin -y $t.id -x $t.colorcsv """ 250TP_COLOR_BASE = """colorspin -y $t.id -x $t.colorcsv -q $t.wss -l $t.loops """
246 251
247TP_COLOR_B = TP_BASE.format("b", TP_COLOR_BASE + "-p $t.cpu ") 252TP_COLOR_B = TP_BASE.format("b", TP_COLOR_BASE + "-p $t.cpu ")
248TP_COLOR_C = TP_BASE.format("c", TP_COLOR_BASE) 253TP_COLOR_C = TP_BASE.format("c", TP_COLOR_BASE)
@@ -255,12 +260,16 @@ TP_CHUNK = """#if $chunk_size > 0
255COLOR_TYPES = ['scheduling', 'locking', 'unmanaged'] 260COLOR_TYPES = ['scheduling', 'locking', 'unmanaged']
256 261
257class ColorMcGenerator(McGenerator): 262class ColorMcGenerator(McGenerator):
263 __SINGLE_PAGE_LOOP_MS = {'ringo': .023}
264
258 def __init__(self, params = {}): 265 def __init__(self, params = {}):
259 super(ColorMcGenerator, self).__init__("MC", 266 super(ColorMcGenerator, self).__init__("MC",
260 templates=[TP_TYPE, TP_CHUNK, TP_COLOR_B, TP_COLOR_C], 267 templates=[TP_ADD, TP_TYPE, TP_CHUNK, TP_COLOR_B, TP_COLOR_C],
261 options=self.__make_options(), 268 options=self.__make_options(),
262 params=self.__extend_params(params)) 269 params=self.__extend_params(params))
263 270
271 self.tasksets = None
272
264 def __extend_params(self, params): 273 def __extend_params(self, params):
265 '''Add in fixed mixed-criticality parameters.''' 274 '''Add in fixed mixed-criticality parameters.'''
266 params['levels'] = 2 275 params['levels'] = 2
@@ -278,6 +287,10 @@ class ColorMcGenerator(McGenerator):
278 287
279 return params 288 return params
280 289
290 def __get_system_name(self):
291 import socket
292 return socket.gethostname().split(".")[0]
293
281 def __make_system_info(self): 294 def __make_system_info(self):
282 info = get_cache_info() 295 info = get_cache_info()
283 296
@@ -298,20 +311,32 @@ class ColorMcGenerator(McGenerator):
298 info = CacheInfo(cache, line=line, page=page, 311 info = CacheInfo(cache, line=line, page=page,
299 ways=ways, sets=sets, colors=colors) 312 ways=ways, sets=sets, colors=colors)
300 313
301 self.system = info 314 self.cache = info
315
316 hostname = self.__get_system_name()
317 if hostname not in self.__SINGLE_PAGE_LOOP_MS:
318 first_host = self.__SINGLE_PAGE_LOOP_MS.keys()[0]
319 log_once("hostname", "No timing info for host %s" % hostname +
320 ", needed to calculate work done per task. Please get the "
321 "timing info and add to __SINGLE_PAGE_LOOP_MS in " +
322 "mc_generators.py. Assuming host %s." % first_host)
323 hostname = first_host
324 self.host = hostname
302 325
303 def __make_options(self): 326 def __make_options(self):
304 self.__make_system_info() 327 self.__make_system_info()
305 328
306 return [GenOption('type', COLOR_TYPES, COLOR_TYPES, 329 return [GenOption('type', COLOR_TYPES, COLOR_TYPES,
307 'Cache management type.'), 330 'Cache management type.'),
308 GenOption('chunk_size', float, [0], 'Chunk size.'), 331 GenOption('host', self.__SINGLE_PAGE_LOOP_MS.keys(), self.host,
309 GenOption('ways', int, [self.system.ways], 'Ways (associativity).'), 332 'System experiment will run on (for calculating work).'),
310 GenOption('colors', int, [self.system.colors], 333 GenOption('chunk_size_ns', float, 0, 'Chunk size. 0 = no chunking.'),
334 GenOption('ways', int, self.cache.ways, 'Ways (associativity).'),
335 GenOption('colors', int, self.cache.colors,
311 'System colors (cache size / ways).'), 336 'System colors (cache size / ways).'),
312 GenOption('page_size', int, [self.system.page], 337 GenOption('page_size', int, self.cache.page,
313 'System page size.'), 338 'System page size.'),
314 GenOption('wss', [float, int], [.5], 339 GenOption('wss', [float, int], .5,
315 'Task working set sizes. Can be expressed as a fraction ' + 340 'Task working set sizes. Can be expressed as a fraction ' +
316 'of the cache.')] 341 'of the cache.')]
317 342
@@ -346,14 +371,37 @@ class ColorMcGenerator(McGenerator):
346 for color, replicas in task.colors.iteritems(): 371 for color, replicas in task.colors.iteritems():
347 f.write("%d, %d\n" % (color, replicas)) 372 f.write("%d, %d\n" % (color, replicas))
348 373
374 def __get_loops(self, task, pages, system):
375 all_pages_loop = self.__SINGLE_PAGE_LOOP_MS[system] * pages
376 return int(task.cost / all_pages_loop) + 1
377
378 def _get_tasks(self, params):
379 # Share tasksets amongst experiments with different types but
380 # identical other parameters for proper comparisons
381 if self.tasksets == None:
382 fields = params.keys()
383 fields.remove("type")
384 self.tasksets = TupleTable( ColMap(fields), lambda:None )
385
386 if params not in self.tasksets:
387 ts = super(ColorMcGenerator, self)._get_tasks(params)
388 self.tasksets[params] = ts
389
390 return self.tasksets[params]
391
349 def _customize(self, task_system, params): 392 def _customize(self, task_system, params):
350 '''Add coloring properties to the mixed-criticality task system.''' 393 '''Add coloring properties to the mixed-criticality task system.'''
394 pages_needed = self.__get_wss_pages(params)
395 real_wss = params['page_size'] * pages_needed
396
351 # Every task needs a unique id for coloring and wss walk order 397 # Every task needs a unique id for coloring and wss walk order
352 all_tasks = [] 398 all_tasks = []
353 for level, tasks in task_system.iteritems(): 399 for level, tasks in task_system.iteritems():
354 all_tasks += tasks 400 all_tasks += tasks
355 for i, task in enumerate(all_tasks): 401 for i, task in enumerate(all_tasks):
356 task.id = i 402 task.id = i
403 task.wss = real_wss
404 task.loops = self.__get_loops(task, pages_needed, params['host'])
357 405
358 c = params['colors'] 406 c = params['colors']
359 w = params['ways'] 407 w = params['ways']
@@ -365,8 +413,6 @@ class ColorMcGenerator(McGenerator):
365 srt_colorer = RandomColorScheme(c, w) 413 srt_colorer = RandomColorScheme(c, w)
366 hrt_colorer = BlockColorScheme(c, w, way_first=True) 414 hrt_colorer = BlockColorScheme(c, w, way_first=True)
367 415
368 pages_needed = self.__get_wss_pages(params)
369
370 hrt_colorer.color(task_system['lvlb'], pages_needed) 416 hrt_colorer.color(task_system['lvlb'], pages_needed)
371 srt_colorer.color(task_system['lvlc'], pages_needed) 417 srt_colorer.color(task_system['lvlc'], pages_needed)
372 418