diff options
-rw-r--r-- | arch/SConscript | 2 | ||||
-rw-r--r-- | cpu/SConscript | 32 | ||||
-rw-r--r-- | dev/pktfifo.cc | 34 | ||||
-rw-r--r-- | dev/pktfifo.hh | 29 | ||||
-rw-r--r-- | dev/sinic.hh | 1 | ||||
-rw-r--r-- | util/stats/barchart.py | 62 | ||||
-rw-r--r-- | util/stats/categories.py | 6 | ||||
-rw-r--r-- | util/stats/chart.py | 1 | ||||
-rw-r--r-- | util/stats/db.py | 2 | ||||
-rw-r--r-- | util/stats/output.py | 37 | ||||
-rwxr-xr-x | util/stats/stats.py | 7 |
11 files changed, 180 insertions, 33 deletions
diff --git a/arch/SConscript b/arch/SConscript index c62e45763..5783b39dd 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -80,7 +80,7 @@ def gen_switch_hdr_string(target, source, env): return "Generating ISA switch header " + str(target[0]) # Build SCons Action object. 'varlist' specifies env vars that this -# action depdnds on; when env['ALL_ISA_LIST'] changes these actions +# action depends on; when env['ALL_ISA_LIST'] changes these actions # should get re-executed. switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, varlist=['ALL_ISA_LIST']) diff --git a/cpu/SConscript b/cpu/SConscript index dbe174660..af6bab4eb 100644 --- a/cpu/SConscript +++ b/cpu/SConscript @@ -32,13 +32,28 @@ import os.path # Import build environment variable from SConstruct. Import('env') +################################################################# +# +# Generate StaticInst execute() method signatures. +# +# There must be one signature for each CPU model compiled in. +# Since the set of compiled-in models is flexible, we generate a +# header containing the appropriate set of signatures on the fly. +# +################################################################# + +# CPU model-specific data is contained in cpu_models.py +# Convert to SCons File node to get path handling models_db = File('cpu_models.py') +# slurp in contents of file execfile(models_db.srcnode().abspath) +# Template for execute() signature. exec_sig_template = ''' virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0; ''' +# Generate header. def gen_cpu_exec_signatures(target, source, env): f = open(str(target[0]), 'w') print >> f, ''' @@ -52,7 +67,22 @@ def gen_cpu_exec_signatures(target, source, env): #endif // __CPU_STATIC_INST_EXEC_SIGS_HH__ ''' -env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures) +# Generate string that gets printed when header is rebuilt +def gen_sigs_string(target, source, env): + return "Generating static_inst_exec_sigs.hh: " \ + + ', '.join(env['CPU_MODELS']) + +# Add command to generate header to environment. +env.Command('static_inst_exec_sigs.hh', models_db, + Action(gen_cpu_exec_signatures, gen_sigs_string, + varlist = ['CPU_MODELS'])) + +################################################################# +# +# Include CPU-model-specific files based on set of models +# specified in CPU_MODELS build option. +# +################################################################# sources = [] diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc index b4fab2d6f..639009be9 100644 --- a/dev/pktfifo.cc +++ b/dev/pktfifo.cc @@ -31,6 +31,36 @@ using namespace std; +bool +PacketFifo::copyout(void *dest, int offset, int len) +{ + char *data = (char *)dest; + if (offset + len >= size()) + return false; + + list<PacketPtr>::iterator p = fifo.begin(); + list<PacketPtr>::iterator end = fifo.end(); + while (len > 0) { + while (offset >= (*p)->length) { + offset -= (*p)->length; + ++p; + } + + if (p == end) + panic("invalid fifo"); + + int size = min((*p)->length - offset, len); + memcpy(data, (*p)->data, size); + offset = 0; + len -= size; + data += size; + ++p; + } + + return true; +} + + void PacketFifo::serialize(const string &base, ostream &os) { @@ -40,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os) paramOut(os, base + ".packets", fifo.size()); int i = 0; - std::list<PacketPtr>::iterator p = fifo.begin(); - std::list<PacketPtr>::iterator end = fifo.end(); + list<PacketPtr>::iterator p = fifo.begin(); + list<PacketPtr>::iterator end = fifo.end(); while (p != end) { (*p)->serialize(csprintf("%s.packet%d", base, i), os); ++p; diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh index e63fd291f..e245840a8 100644 --- a/dev/pktfifo.hh +++ b/dev/pktfifo.hh @@ -127,6 +127,35 @@ class PacketFifo fifo.erase(i); } + bool copyout(void *dest, int offset, int len); + + int countPacketsBefore(iterator end) + { + iterator i = fifo.begin(); + int count = 0; + + while (i != end) { + ++count; + ++i; + } + + return count; + } + + int countPacketsAfter(iterator i) + { + iterator end = fifo.end(); + int count = 0; + + while (i != end) { + ++count; + ++i; + } + + return count; + } + + /** * Serialization stuff */ diff --git a/dev/sinic.hh b/dev/sinic.hh index 97ebf4c30..c4027be86 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -280,7 +280,6 @@ class Device : public Base Fault iprRead(Addr daddr, int cpu, uint64_t &result); Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - void regWrite(Addr daddr, int cpu, const uint8_t *data); Tick cacheAccess(MemReqPtr &req); /** diff --git a/util/stats/barchart.py b/util/stats/barchart.py index dd3bf0180..5d6dd0ab1 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -42,13 +42,18 @@ class BarChart(ChartOptions): super(BarChart, self).__init__(default, **kwargs) self.inputdata = None self.chartdata = None + self.inputerr = None + self.charterr = None def gen_colors(self, count): cmap = matplotlib.cm.get_cmap(self.colormap) if count == 1: return cmap([ 0.5 ]) - else: - return cmap(arange(count) / float(count - 1)) + + if count < 5: + return cmap(arange(5) / float(4))[:count] + + return cmap(arange(count) / float(count - 1)) # The input data format does not match the data format that the # graph function takes because it is intuitive. The conversion @@ -89,6 +94,32 @@ class BarChart(ChartOptions): data = property(get_data, set_data) + def set_err(self, err): + if err is None: + self.inputerr = None + self.charterr = None + return + + err = array(err) + dim = len(shape(err)) + if dim not in (1, 2, 3): + raise AttributeError, "Input err must be a 1, 2, or 3d matrix" + self.inputerr = err + + if dim == 1: + self.charterr = array([[err]]) + + if dim == 2: + self.charterr = transpose([err], axes=(2,0,1)) + + if dim == 3: + self.charterr = transpose(err, axes=(1,2,0)) + + def get_err(self): + return self.inputerr + + err = property(get_err, set_err) + # Graph the chart data. # Input is a 3d matrix that describes a plot that has multiple # groups, multiple bars in each group, and multiple values stacked @@ -123,6 +154,9 @@ class BarChart(ChartOptions): dim = len(shape(self.inputdata)) cshape = shape(self.chartdata) + if self.charterr is not None and shape(self.charterr) != cshape: + raise AttributeError, 'Dimensions of error and data do not match' + if dim == 1: colors = self.gen_colors(cshape[2]) colors = [ [ colors ] * cshape[1] ] * cshape[0] @@ -143,7 +177,8 @@ class BarChart(ChartOptions): inner_axes = None if self.xsubticks is not None: color = self.figure.get_facecolor() - self.metaaxes = self.figure.add_axes(self.figure_size, axisbg=color, frameon=False) + self.metaaxes = self.figure.add_axes(self.figure_size, + axisbg=color, frameon=False) for tick in self.metaaxes.xaxis.majorTicks: tick.tick1On = False tick.tick2On = False @@ -174,8 +209,11 @@ class BarChart(ChartOptions): for j,bardata in enumerate(stackdata): bardata = array(bardata) ind = arange(len(bardata)) + i * width + center + yerr = None + if self.charterr is not None: + yerr = self.charterr[i][j] bar = self.axes.bar(ind, bardata, width, bottom=bottom, - color=colors[i][j]) + color=colors[i][j], yerr=yerr) if self.xsubticks is not None: self.metaaxes.bar(ind, [0] * len(bardata), width) stack.append(bar) @@ -202,9 +240,11 @@ class BarChart(ChartOptions): outer_axes.set_xticklabels(self.xticks) if self.xsubticks is not None: - inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) + numticks = (cshape[0] + 1) * cshape[2] + inner_axes.set_xticks(arange(numticks) * width + 2 * center) self.xsubticks.append('') - inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, rotation=90) + inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, + rotation=90) if self.legend is not None: if dim == 1: @@ -215,8 +255,12 @@ class BarChart(ChartOptions): number = len(bars[0]) lbars = [ bars[0][number - j - 1][0] for j in xrange(number)] - self.figure.legend(lbars, self.legend, self.legend_loc, - prop=FontProperties(size=self.legend_size)) + if self.fig_legend: + self.figure.legend(lbars, self.legend, self.legend_loc, + prop=FontProperties(size=self.legend_size)) + else: + self.axes.legend(lbars, self.legend, self.legend_loc, + prop=FontProperties(size=self.legend_size)) if self.title is not None: self.axes.set_title(self.title) @@ -240,7 +284,7 @@ class BarChart(ChartOptions): ylabel = [] #if self.ylabel: # ylabel = [ self.ylabel[i] ] - f.write(', '.join(ylabel + [ '%f' % val for val in row]) + '\n') + f.write(', '.join(ylabel + [ '%f' % v for v in row]) + '\n') if dim == 3: f.write("don't do 3D csv files\n") pass diff --git a/util/stats/categories.py b/util/stats/categories.py index 8d5d506a2..6d8568879 100644 --- a/util/stats/categories.py +++ b/util/stats/categories.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,10 +33,14 @@ func_categories = { \ 'skb_clone_fraglist' : 'buffer', 'skb_seq_read' : 'buffer', 'sock_alloc_send_skb' : 'buffer', + 'sinic_rxskb_alloc' : 'buffer', # Copy functions + 'sinic_copyfrom' : 'copy', '__copy_user' : 'copy', 'skb_copy_bits' : 'copy', + 'skb_copy_datagram_iovec' : 'copy', + 'sinic_vcopy_iov' : 'idle', # Driver functions 'do_tx_done' : 'driver', diff --git a/util/stats/chart.py b/util/stats/chart.py index 095620172..369a57fc6 100644 --- a/util/stats/chart.py +++ b/util/stats/chart.py @@ -31,6 +31,7 @@ class ChartOptions(object): defaults = { 'chart_size' : (8, 4), 'figure_size' : [0.1, 0.1, 0.6, 0.85], 'title' : None, + 'fig_legend' : True, 'legend' : None, 'legend_loc' : 'upper right', 'legend_size' : 6, diff --git a/util/stats/db.py b/util/stats/db.py index d9b78c7d1..c0e7796eb 100644 --- a/util/stats/db.py +++ b/util/stats/db.py @@ -158,7 +158,7 @@ class Database(object): return None from info import ProxyError, scalar, vector, value, values, total, len - if system is None and hasattr('system', job): + if system is None and hasattr(job, 'system'): system = job.system if system is not None: diff --git a/util/stats/output.py b/util/stats/output.py index e67751bbc..abfb8d901 100644 --- a/util/stats/output.py +++ b/util/stats/output.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -103,15 +103,17 @@ class StatOutput(ChartOptions): else: groups.append(group) - if not groupopts: - raise AttributeError, 'No group selected for graph group' + has_group = bool(groupopts) + if has_group: + groupopts = [ group for group in crossproduct(groupopts) ] + else: + groupopts = [ None ] - if not baropts: + if baropts: + baropts = [ bar for bar in crossproduct(baropts) ] + else: raise AttributeError, 'No group selected for graph bars' - groupopts = [ group for group in crossproduct(groupopts) ] - baropts = [ bar for bar in crossproduct(baropts) ] - directory = expanduser(graphdir) if not isdir(directory): os.mkdir(directory) @@ -124,12 +126,13 @@ class StatOutput(ChartOptions): for options in self.jobfile.options(groups): chart = BarChart(self) - data = zeros((len(groupopts), len(baropts)), Float) data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ] enabled = False stacked = 0 for g,gopt in enumerate(groupopts): for b,bopt in enumerate(baropts): + if gopt is None: + gopt = [] job = self.jobfile.job(options + gopt + bopt) if not job: continue @@ -168,19 +171,24 @@ class StatOutput(ChartOptions): if data.sum() == 0: continue + dim = len(data.shape) x = data.shape[0] - y = data.shape[1] xkeep = [ i for i in xrange(x) if data[i].sum() != 0 ] + y = data.shape[1] ykeep = [ i for i in xrange(y) if data[:,i].sum() != 0 ] data = data.take(xkeep, axis=0) data = data.take(ykeep, axis=1) + if not has_group: + data = data.take([ 0 ], axis=0) chart.data = data - gopts = [ groupopts[i] for i in xkeep ] - bopts = [ baropts[i] for i in ykeep ] + bopts = [ baropts[i] for i in ykeep ] bdescs = [ ' '.join([o.desc for o in opt]) for opt in bopts] - gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts] + + if has_group: + gopts = [ groupopts[i] for i in xkeep ] + gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts] if chart.legend is None: if stacked: @@ -192,7 +200,10 @@ class StatOutput(ChartOptions): chart.legend = bdescs if chart.xticks is None: - chart.xticks = gdescs + if has_group: + chart.xticks = gdescs + else: + chart.xticks = [] chart.graph() names = [ opt.name for opt in options ] diff --git a/util/stats/stats.py b/util/stats/stats.py index b75d9fec0..08281287f 100755 --- a/util/stats/stats.py +++ b/util/stats/stats.py @@ -262,6 +262,7 @@ def commands(options, command, args): from output import StatOutput output = StatOutput(options.jobfile, source) output.xlabel = 'System Configuration' + output.colormap = 'RdYlGn' if command == 'stat' or command == 'formula': if len(args) != 1: @@ -286,7 +287,6 @@ def commands(options, command, args): raise CommandException from info import ProxyGroup - sim_seconds = source['sim_seconds'] proxy = ProxyGroup(system = source[options.system]) system = proxy.system @@ -294,7 +294,6 @@ def commands(options, command, args): bytes = etherdev.rxBytes + etherdev.txBytes kbytes = bytes / 1024 packets = etherdev.rxPackets + etherdev.txPackets - bps = etherdev.rxBandwidth + etherdev.txBandwidth def display(): if options.graph: @@ -337,7 +336,7 @@ def commands(options, command, args): return if command == 'pps': - output.stat = packets / sim_seconds + output.stat = packets / source['sim_seconds'] output.ylabel = 'Packets/s' display() return @@ -355,7 +354,7 @@ def commands(options, command, args): if command == 'txbps': output.stat = etherdev.txBandwidth / 1e9 if command == 'bps': - output.stat = bps / 1e9 + output.stat = (etherdev.rxBandwidth + etherdev.txBandwidth) / 1e9 output.ylabel = 'Bandwidth (Gbps)' output.ylim = [ 0.0, 10.0 ] |