From c67d967055a077008644473ccc261e591e71ba7e Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 8 Dec 2004 18:30:06 -0500 Subject: [PATCH 01/12] compress main memory in checkpoints SConscript: Add zlib to the build always --HG-- extra : convert_revision : fae49fbbba371660e171d7e8328894a74c846ec5 --- SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConscript b/SConscript index 3938f792f..dedfe1aaa 100644 --- a/SConscript +++ b/SConscript @@ -413,12 +413,12 @@ else: obj_desc_files += syscall_emulation_obj_desc_files extra_libraries = [] +env.Append(LIBS=['z']) if env['USE_MYSQL']: sources += mysql_sources env.Append(CPPDEFINES = 'USE_MYSQL') env.Append(CPPDEFINES = 'STATS_BINNING') env.Append(CPPPATH=['/usr/local/include/mysql', '/usr/include/mysql']) - env.Append(LIBS=['z']) if os.path.isdir('/usr/lib64'): env.Append(LIBPATH=['/usr/lib64/mysql']) else: From f3e89d3991bed9c2ad33e29d1f61a11860db1f52 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 9 Dec 2004 01:07:08 -0500 Subject: [PATCH 03/12] Change Bus template parameter to BusType (to avoid confusion with Bus class). Change Mem template parameter to MemType while we're at it. dev/io_device.hh: Change Bus template parameter to BusType (to avoid confusion with Bus class). --HG-- extra : convert_revision : dca8effb177535b3624ef08a3d3b8afab720390b --- dev/io_device.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/io_device.hh b/dev/io_device.hh index f49afc0a6..8c9dc4a35 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -34,7 +34,7 @@ class BaseInterface; class Bus; class HierParams; -template class DMAInterface; +template class DMAInterface; class PioDevice : public FunctionalMemory { From d0bff50bbabf63de382f202dba956cd7b9b47de7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 13 Dec 2004 12:55:13 -0500 Subject: [PATCH 04/12] Fix up the random number stuff. SConscript: compile the random number generator stuff into m5 base/random.cc: we need to define our destructor base/random.hh: Since there's no state, just makes all of these get functions static --HG-- extra : convert_revision : 9d4b8abd57367391a8ecda3914b1d912d9c64185 --- SConscript | 1 + base/random.cc | 2 +- base/random.hh | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/SConscript b/SConscript index dedfe1aaa..f6c472216 100644 --- a/SConscript +++ b/SConscript @@ -65,6 +65,7 @@ base_sources = Split(''' base/pollevent.cc base/python.cc base/range.cc + base/random.cc base/sat_counter.cc base/socket.cc base/statistics.cc diff --git a/base/random.cc b/base/random.cc index f18ed546d..9a4562e8a 100644 --- a/base/random.cc +++ b/base/random.cc @@ -39,7 +39,7 @@ class RandomContext : public ParamContext public: RandomContext(const string &_iniSection) : ::ParamContext(_iniSection) {} - ~RandomContext(); + ~RandomContext() {} void checkParams(); }; diff --git a/base/random.hh b/base/random.hh index 5169c548a..0bfed100c 100644 --- a/base/random.hh +++ b/base/random.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __RANDOM_HH__ -#define __RANDOM_HH__ +#ifndef __BASE_RANDOM_HH__ +#define __BASE_RANDOM_HH__ #include "sim/host.hh" @@ -45,56 +45,56 @@ struct Random struct Random { - uint8_t get() + static uint8_t get() { return getLong() & (uint8_t)-1; } }; struct Random { - int16_t get() + static int16_t get() { return getLong() & (int16_t)-1; } }; struct Random { - uint16_t get() + static uint16_t get() { return getLong() & (uint16_t)-1; } }; struct Random { - int32_t get() + static int32_t get() { return (int32_t)getLong(); } }; struct Random { - uint32_t get() + static uint32_t get() { return (uint32_t)getLong(); } }; struct Random { - int64_t get() + static int64_t get() { return (int64_t)getLong() << 32 || (uint64_t)getLong(); } }; struct Random { - uint64_t get() + static uint64_t get() { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); } }; struct Random { - float get() + static float get() { return getDouble(); } }; struct Random { - double get() + static double get() { return getDouble(); } }; -#endif // __RANDOM_HH__ +#endif // __BASE_RANDOM_HH__ From d3d750151daf582cc2446d3dcb4f0fd5086b56ab Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Tue, 14 Dec 2004 13:15:54 -0500 Subject: [PATCH 05/12] Modified to work with do_events No multiple requests to the same block outstanding from the same tester Using false sharing, each tester only access a single byte within the block based on which tester it is Allow more cycles before signalling deadlock, with do_events it may take some time with NACK/retry and many proccessors --HG-- extra : convert_revision : 4c8eab99082c53840a5ad2a926457dfc27f23b77 --- cpu/memtest/memtest.cc | 49 +++++++++++++++++++++++++++++++++++++++--- cpu/memtest/memtest.hh | 15 ++++++++----- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 6584a62ba..e967c79da 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -28,9 +28,10 @@ // FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded -#include -#include #include +#include +#include +#include #include #include "base/misc.hh" @@ -44,6 +45,8 @@ using namespace std; +int TESTER_ALLOCATOR=0; + MemTest::MemTest(const string &name, MemInterface *_cache_interface, FunctionalMemory *main_mem, @@ -111,6 +114,8 @@ MemTest::MemTest(const string &name, noResponseCycles = 0; numReads = 0; tickEvent.schedule(0); + + id = TESTER_ALLOCATOR++; } static void @@ -127,6 +132,11 @@ printData(ostream &os, uint8_t *data, int nbytes) void MemTest::completeRequest(MemReqPtr &req, uint8_t *data) { + //Remove the address from the list of outstanding + std::set::iterator removeAddr = outstandingAddrs.find(req->paddr); + assert(removeAddr != outstandingAddrs.end()); + outstandingAddrs.erase(removeAddr); + switch (req->cmd) { case Read: if (memcmp(req->data, data, req->size) != 0) { @@ -158,6 +168,10 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data) break; case Copy: + //Also remove dest from outstanding list + removeAddr = outstandingAddrs.find(req->dest); + assert(removeAddr != outstandingAddrs.end()); + outstandingAddrs.erase(removeAddr); numCopiesStat++; break; @@ -212,7 +226,7 @@ MemTest::tick() if (!tickEvent.scheduled()) tickEvent.schedule(curTick + 1); - if (++noResponseCycles >= 5000) { + if (++noResponseCycles >= 500000) { cerr << name() << ": deadlocked at cycle " << curTick << endl; fatal(""); } @@ -232,6 +246,16 @@ MemTest::tick() unsigned source_align = rand() % 100; unsigned dest_align = rand() % 100; + //If we aren't doing copies, use id as offset, and do a false sharing + //mem tester + if (percentCopies == 0) { + //We can eliminate the lower bits of the offset, and then use the id + //to offset within the blks + offset1 &= ~63; //Not the low order bits + offset1 += id; + access_size = 0; + } + MemReqPtr req = new MemReq(); if (cacheable < percentUncacheable) { @@ -251,6 +275,13 @@ MemTest::tick() if (cmd < percentReads) { // read + + //For now we only allow one outstanding request per addreess per tester + //This means we assume CPU does write forwarding to reads that alias something + //in the cpu store buffer. + if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return; + else outstandingAddrs.insert(req->paddr); + req->cmd = Read; uint8_t *result = new uint8_t[8]; checkMem->access(Read, req->paddr, result, req->size); @@ -273,6 +304,13 @@ MemTest::tick() } } else if (cmd < (100 - percentCopies)){ // write + + //For now we only allow one outstanding request per addreess per tester + //This means we assume CPU does write forwarding to reads that alias something + //in the cpu store buffer. + if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return; + else outstandingAddrs.insert(req->paddr); + req->cmd = Write; memcpy(req->data, &data, req->size); checkMem->access(Write, req->paddr, req->data, req->size); @@ -298,6 +336,11 @@ MemTest::tick() // copy Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1; Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2; + if (outstandingAddrs.find(source) != outstandingAddrs.end()) return; + else outstandingAddrs.insert(source); + if (outstandingAddrs.find(dest) != outstandingAddrs.end()) return; + else outstandingAddrs.insert(dest); + if (source_align >= percentSourceUnaligned) { source = blockAddr(source); } diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 72e0709d9..43b17a713 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -29,13 +29,14 @@ #ifndef __MEMTEST_HH__ #define __MEMTEST_HH__ -#include "sim/sim_object.hh" -#include "mem/mem_interface.hh" -#include "mem/functional_mem/functional_memory.hh" -#include "cpu/base_cpu.hh" -#include "cpu/exec_context.hh" +#include #include "base/statistics.hh" +#include "cpu/base_cpu.hh" +#include "cpu/exec_context.hh" +#include "mem/functional_mem/functional_memory.hh" +#include "mem/mem_interface.hh" +#include "sim/sim_object.hh" #include "sim/stats.hh" class MemTest : public BaseCPU @@ -87,6 +88,10 @@ class MemTest : public BaseCPU unsigned percentCopies; // target percentage of copy accesses unsigned percentUncacheable; + int id; + + std::set outstandingAddrs; + unsigned blockSize; Addr blockAddrMask; From ed7926664f25f1b5fb2871956c30868027939e15 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 12 Jan 2005 13:41:06 -0500 Subject: [PATCH 11/12] Update for newer MySQLdb util/stats/db.py: Update for newer MySQLdb, the result of a blob in a query is an array.array now, so we need to convert that to a string --HG-- extra : convert_revision : 32732983d3d7141755085ec4913fdae057edc67f --- util/stats/db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/stats/db.py b/util/stats/db.py index 4cba82446..495cdb5b5 100644 --- a/util/stats/db.py +++ b/util/stats/db.py @@ -171,7 +171,7 @@ class Database(object): self.query('select * from formulas') for id,formula in self.cursor.fetchall(): - self.allFormulas[int(id)] = formula + self.allFormulas[int(id)] = formula.tostring() StatData.db = self self.query('select * from stats') From 0f0c80ad8c7ee871b848bcbc9e83f9f56fd724a4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 12 Jan 2005 13:44:47 -0500 Subject: [PATCH 12/12] More graph output junk util/stats/stats.py: Add the graphing output for 6GHz and 8GHz runs --HG-- extra : convert_revision : fae3763c213e4b839735761bf91fa37e1b4f343c --- util/stats/stats.py | 77 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/util/stats/stats.py b/util/stats/stats.py index 68ba2b8ea..05ee1b4d3 100755 --- a/util/stats/stats.py +++ b/util/stats/stats.py @@ -39,7 +39,73 @@ def unique(list): map(set.__setitem__, list, []) return set.keys() +def graphdata68(runs, options, tag, label, value): + import info + configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] + benchmarks = [ 'm', 's', 'snt', 'nb1', 'w1', 'w2', 'w3', 'w4', 'nm', 'ns', 'nw1', 'nw2', 'nw3' ] + dmas = [ 'x' ] + caches = [ '2', '4' ] + + names = [] + + bench_system = { + 'm' : 'client', + 's' : 'client', + 'snt' : 'client', + 'nb1' : 'server', + 'nb2' : 'server', + 'nt1' : 'server', + 'nt2' : 'server', + 'w1' : 'server', + 'w2' : 'server', + 'w3' : 'server', + 'w4' : 'server', + 'w1s' : 'server', + 'w2s' : 'server', + 'w3s' : 'server', + 'ns' : 'natbox', + 'nm' : 'natbox', + 'nw1' : 'natbox', + 'nw2' : 'natbox', + 'nw3' : 'natbox' + } + + for bench in benchmarks: + if bench_system[bench] != options.system: + continue + + for dma in dmas: + for cache in caches: + names.append([bench, dma, cache]) + + for bench,dma,cache in names: + base = '%s.%s.%s' % (bench, dma, cache) + fname = 'data/%s.%s.68.dat' % (tag, base) + f = open(fname, 'w') + print >>f, '#set TITLE = ' + print >>f, '#set ylbl = %s' % label + #print >>f, '#set sublabels = %s' % ' '.join(configs) + print >>f, '#set sublabels = ste hte htd ocm occ ocs' + + for speed,freq in zip(['s', '6', '8', 'q'],['4GHz', '6GHz','8GHz', '10GHz']): + print >>f, '"%s"' % freq, + for conf in configs: + name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed) + run = info.source.allRunNames[name] + info.display_run = run.run; + val = float(value) + if val == 1e300*1e300: + print >>f, 0.0, + else: + print >>f, "%f" % val, + print >>f + f.close() + def graphdata(runs, options, tag, label, value): + if options.graph68: + graphdata68(runs, options, tag, label, value) + return + import info configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ] @@ -85,10 +151,10 @@ def graphdata(runs, options, tag, label, value): base = '%s.%s.%s' % (bench, dma, cache) fname = 'data/%s.%s.dat' % (tag, base) f = open(fname, 'w') - print >>f, '#set TITLE = %s' % base - print >>f, '#set xlbl = Configuration' + print >>f, '#set TITLE = ' print >>f, '#set ylbl = %s' % label - print >>f, '#set sublabels = %s' % ' '.join(configs) + #print >>f, '#set sublabels = %s' % ' '.join(configs) + print >>f, '#set sublabels = ste hte htd ocm occ ocs' for speed,freq in zip(['s', 'q'],['4GHz','10GHz']): print >>f, '"%s"' % freq, @@ -578,9 +644,12 @@ if __name__ == '__main__': options.get = None options.binned = False options.graph = False + options.graph68 = False - opts, args = getopts(sys.argv[1:], '-BEFGd:g:h:pr:s:u:') + opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:') for o,a in opts: + if o == '-6': + options.graph68 = True if o == '-B': options.binned = True if o == '-E':