diff options
-rw-r--r-- | SConscript | 1 | ||||
-rw-r--r-- | base/random.cc | 2 | ||||
-rw-r--r-- | base/random.hh | 24 | ||||
-rw-r--r-- | cpu/memtest/memtest.cc | 49 | ||||
-rw-r--r-- | cpu/memtest/memtest.hh | 15 | ||||
-rw-r--r-- | dev/io_device.hh | 2 |
6 files changed, 71 insertions, 22 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<int8_t> struct Random<uint8_t> { - uint8_t get() + static uint8_t get() { return getLong() & (uint8_t)-1; } }; struct Random<int16_t> { - int16_t get() + static int16_t get() { return getLong() & (int16_t)-1; } }; struct Random<uint16_t> { - uint16_t get() + static uint16_t get() { return getLong() & (uint16_t)-1; } }; struct Random<int32_t> { - int32_t get() + static int32_t get() { return (int32_t)getLong(); } }; struct Random<uint32_t> { - uint32_t get() + static uint32_t get() { return (uint32_t)getLong(); } }; struct Random<int64_t> { - int64_t get() + static int64_t get() { return (int64_t)getLong() << 32 || (uint64_t)getLong(); } }; struct Random<uint64_t> { - uint64_t get() + static uint64_t get() { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); } }; struct Random<float> { - float get() + static float get() { return getDouble(); } }; struct Random<double> { - double get() + static double get() { return getDouble(); } }; -#endif // __RANDOM_HH__ +#endif // __BASE_RANDOM_HH__ 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 <string> -#include <sstream> #include <iomanip> +#include <set> +#include <sstream> +#include <string> #include <vector> #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<unsigned>::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 <set> #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<unsigned> outstandingAddrs; + unsigned blockSize; Addr blockAddrMask; 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 Bus> class DMAInterface; +template <class BusType> class DMAInterface; class PioDevice : public FunctionalMemory { |