From d4e1f926d310ec8ae73cfd2d3c51ca5f6239cb36 Mon Sep 17 00:00:00 2001 From: feldergast Date: Tue, 25 Apr 2017 11:14:24 -0600 Subject: [PATCH 1/3] Remove the use of boost::variant. Made a variant-type class specific to type Addr and MemEvent*. --- .../elements/memHierarchy/cacheController.cc | 32 +++++++-------- .../memHierarchy/cacheEventProcessing.cc | 2 +- .../memHierarchy/directoryController.cc | 2 +- src/sst/elements/memHierarchy/mshr.cc | 40 +++++++++---------- src/sst/elements/memHierarchy/mshr.h | 25 +++++++++++- 5 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/sst/elements/memHierarchy/cacheController.cc b/src/sst/elements/memHierarchy/cacheController.cc index 1db246a7b1..1b4a59884e 100644 --- a/src/sst/elements/memHierarchy/cacheController.cc +++ b/src/sst/elements/memHierarchy/cacheController.cc @@ -506,14 +506,14 @@ void Cache::activatePrevEvents(Addr baseAddr) { bool writebackInProgress = false; // Use this to allow replay of pointers but NOT events for this addr because an eviction is in progress // Self-pointer check -> remove it and record that we have it if needed - if ((*entries.begin()).elem.type() == typeid(Addr) && boost::get((*entries.begin()).elem) == baseAddr) { + if ((*entries.begin()).elem.isAddr() && ((*entries.begin()).elem).getAddr() == baseAddr) { entries.erase(entries.begin()); writebackInProgress = true; } for (vector::iterator it = entries.begin(); it != entries.end(); i++) { - if ((*it).elem.type() == typeid(Addr)) { /* Pointer Type */ - Addr pointerAddr = boost::get((*it).elem); + if ((*it).elem.isAddr()) { /* Pointer Type */ + Addr pointerAddr = ((*it).elem).getAddr(); #ifdef __SST_DEBUG_OUTPUT__ if (DEBUG_ALL || DEBUG_ADDR == baseAddr) d_->debug(_L6_,"Pointer Addr: %" PRIx64 "\n", pointerAddr); #endif @@ -526,8 +526,8 @@ void Cache::activatePrevEvents(Addr baseAddr) { // This entry list shouldn't include pointers unless a writeback occured (and even then...) vector pointerEntries = mshr_->removeAll(pointerAddr); for (vector::iterator it2 = pointerEntries.begin(); it2 != pointerEntries.end(); i++) { - if ((*it2).elem.type() != typeid(MemEvent*)) { - Addr elemAddr = boost::get((*it2).elem); + if ((*it2).elem.isAddr()) { + Addr elemAddr = ((*it2).elem).getAddr(); if (elemAddr == pointerAddr) { #ifdef __SST_DEBUG_OUTPUT__ d_->debug(_L5_, "Cache eviction raced with stalled request, wait for AckPut\n"); @@ -539,7 +539,7 @@ void Cache::activatePrevEvents(Addr baseAddr) { this->getName().c_str(), pointerAddr, getCurrentSimTimeNano()); } } - cont = activatePrevEvent(boost::get((*it2).elem), pointerEntries, pointerAddr, it2, i); + cont = activatePrevEvent(((*it2).elem).getEvent(), pointerEntries, pointerAddr, it2, i); if (!cont) break; } entries.erase(it); // Erase processed pointer @@ -547,8 +547,8 @@ void Cache::activatePrevEvents(Addr baseAddr) { // Check if we need to stop because a new event is in our mshr thanks to the processing of the pointer events? if (mshr_->isHit(baseAddr)) { bool stop = false; - if (entries.begin()->elem.type() == typeid(MemEvent*)) { - MemEvent * front = boost::get((entries.begin())->elem); + if (entries.begin()->elem.isEvent()) { + MemEvent * front = ((entries.begin())->elem).getEvent(); if (front->getCmd() != Inv && front->getCmd() != FetchInv && front->getCmd() != FetchInvX) { stop = true; } @@ -561,7 +561,7 @@ void Cache::activatePrevEvents(Addr baseAddr) { } } } else { /* MemEvent Type */ - Command cmd = boost::get((entries.begin())->elem)->getCmd(); + Command cmd = ((entries.begin())->elem).getEvent()->getCmd(); if (writebackInProgress) { if (cmd != Inv && cmd != FetchInv && cmd != FetchInvX) { mshr_->insertAll(baseAddr, entries); @@ -570,7 +570,7 @@ void Cache::activatePrevEvents(Addr baseAddr) { writebackInProgress = false; } } - cont = activatePrevEvent(boost::get((*it).elem), entries, baseAddr, it, i); + cont = activatePrevEvent(((*it).elem).getEvent(), entries, baseAddr, it, i); if (!cont) break; } } @@ -601,8 +601,8 @@ bool Cache::activatePrevEvent(MemEvent* event, vector& _entries, Addr /* However we do need to replay requests from lower levels! (Like Inv) Otherwise deadlock! */ if (mshr_->isHit(_addr)) { bool stop = false; - if (_entries.begin()->elem.type() == typeid(MemEvent*)) { - MemEvent * front = boost::get((_entries.begin())->elem); + if (_entries.begin()->elem.isEvent()) { + MemEvent * front = ((_entries.begin())->elem).getEvent(); if (front->getCmd() != Inv && front->getCmd() != FetchInv && front->getCmd() != FetchInvX) stop = true; } else { stop = true; @@ -697,12 +697,12 @@ void Cache::reActivateEventWaitingForUserLock(CacheLine* cacheLine) { Extras --------------------------------------- */ MemEvent* Cache::getOrigReq(const vector entries) { - if (entries.front().elem.type() != typeid(MemEvent*)) { + if (entries.front().elem.isAddr()) { d_->fatal(CALL_INFO, -1, "%s, Error: Request at front of the mshr is not of type MemEvent. Time = %" PRIu64 "\n", this->getName().c_str(), getCurrentSimTimeNano()); } - return boost::get(entries.front().elem); + return (entries.front().elem).getEvent(); } @@ -809,7 +809,7 @@ void Cache::printLine(Addr addr) { bool operator== ( const mshrType& n1, const mshrType& n2) { - if (n1.elem.type() == typeid(Addr)) return false; - return(boost::get(n1.elem) == boost::get(n2.elem)); + if (n1.elem.isAddr()) return false; + return((n1.elem).getEvent() == (n2.elem).getEvent()); } diff --git a/src/sst/elements/memHierarchy/cacheEventProcessing.cc b/src/sst/elements/memHierarchy/cacheEventProcessing.cc index 234f558020..8ad5ba2d6a 100644 --- a/src/sst/elements/memHierarchy/cacheEventProcessing.cc +++ b/src/sst/elements/memHierarchy/cacheEventProcessing.cc @@ -357,7 +357,7 @@ void Cache::processNoncacheable(MemEvent* event, Command cmd, Addr baseAddr) { // Flushes can be returned out of order since they don't neccessarily require a memory access so we need to actually search the MSHRs vector * entries = mshrNoncacheable_->getAll(baseAddr); for (vector::iterator it = entries->begin(); it != entries->end(); it++) { - MemEvent * candidate = boost::get(it->elem); + MemEvent * candidate = (it->elem).getEvent(); if (candidate->getCmd() == FlushLine || candidate->getCmd() == FlushLineInv) { // All entries are events so no checking for pointer vs event needed if (candidate->getID().first == event->getResponseToID().first && candidate->getID().second == event->getResponseToID().second) { origRequest = candidate; diff --git a/src/sst/elements/memHierarchy/directoryController.cc b/src/sst/elements/memHierarchy/directoryController.cc index ba7759899c..9b7f965cc7 100644 --- a/src/sst/elements/memHierarchy/directoryController.cc +++ b/src/sst/elements/memHierarchy/directoryController.cc @@ -1681,7 +1681,7 @@ void DirectoryController::replayWaitingEvents(Addr addr) { if (mshr->isHit(addr)) { vector replayEntries = mshr->removeAll(addr); for (vector::reverse_iterator it = replayEntries.rbegin(); it != replayEntries.rend(); it++) { - MemEvent *ev = boost::get((*it).elem); + MemEvent *ev = ((*it).elem).getEvent(); #ifdef __SST_DEBUG_OUTPUT__ if (DEBUG_ALL || DEBUG_ADDR == addr) { dbg.debug(_L5_, "Reactivating event. Cmd = %s, BaseAddr = 0x%" PRIx64 ", Addr = 0x%" PRIx64 "\n", CommandString[ev->getCmd()], ev->getBaseAddr(), ev->getAddr()); diff --git a/src/sst/elements/memHierarchy/mshr.cc b/src/sst/elements/memHierarchy/mshr.cc index 1e0cff3703..e8ecfbce51 100644 --- a/src/sst/elements/memHierarchy/mshr.cc +++ b/src/sst/elements/memHierarchy/mshr.cc @@ -22,16 +22,16 @@ using namespace SST::MemHierarchy; struct MSHREntryCompare { enum Type {Event, Pointer}; MSHREntryCompare( mshrType* _m ) : m_(_m) { - if (m_->elem.type() == typeid(MemEvent*)) type_ = Event; + if (m_->elem.isEvent()) type_ = Event; else type_ = Pointer; } bool operator() (mshrType& _n) { if (type_ == Event) { - if (_n.elem.type() == typeid(MemEvent*)) return boost::get(m_->elem) == boost::get(_n.elem); + if (_n.elem.isEvent()) return (m_->elem).getEvent() == (_n.elem).getEvent(); return false; } else{ - if (_n.elem.type() == typeid(Addr)) return boost::get(m_->elem) == boost::get(_n.elem); + if (_n.elem.isAddr()) return (m_->elem).getAddr() == (_n.elem).getAddr(); return false; } } @@ -142,7 +142,7 @@ bool MSHR::exists(Addr baseAddr) { vector * queue = &((it->second).mshrQueue); vector::iterator frontEntry = queue->begin(); if (frontEntry == queue->end()) return false; - return (frontEntry->elem.type() == typeid(MemEvent*)); + return (frontEntry->elem.isEvent()); } bool MSHR::isHit(Addr baseAddr) { return (map_.find(baseAddr) != map_.end()) && (map_.find(baseAddr)->second.mshrQueue.size() > 0); } @@ -173,10 +173,10 @@ MemEvent* MSHR::lookupFront(Addr baseAddr) { d2_->fatal(CALL_INFO,-1, "%s (MSHR), Error: mshr did not find entry with address 0x%" PRIx64 "\n", ownerName_.c_str(), baseAddr); } vector queue = (it->second).mshrQueue; - if (queue.front().elem.type() != typeid(MemEvent*)) { + if (queue.front().elem.isAddr()) { d2_->fatal(CALL_INFO,-1, "%s (MSHR), Error: front entry in mshr is not of type MemEvent. Addr = 0x%" PRIx64 "\n", ownerName_.c_str(), baseAddr); } - return boost::get(queue.front().elem); + return (queue.front().elem).getEvent(); } /* Public insertion methods @@ -267,9 +267,9 @@ bool MSHR::insertAll(Addr baseAddr, vector& events) { int trueSize = 0; int prefetches = 0; for (vector::iterator it = events.begin(); it != events.end(); it++) { - if ((*it).elem.type() == typeid(MemEvent*)) { + if ((*it).elem.isEvent()) { trueSize++; - if ((boost::get(it->elem))->isPrefetch()) + if (((it->elem)).getEvent()->isPrefetch()) prefetches++; } } @@ -303,8 +303,8 @@ bool MSHR::insertInv(Addr baseAddr, mshrType entry, bool inProgress) { /*int i = 0; for (it = map_[baseAddr].mshrQueue.begin(); it != map_[baseAddr].mshrQueue.end(); it++) { if (inProgress && it == map_[baseAddr].mshrQueue.begin()) continue; - if (it->elem.type() == typeid(MemEvent*)) { - MemEvent * ev = boost::get(it->elem); + if (it->elem.isEvent()) { + MemEvent * ev = getEvent(it->elem); if (ev->getCmd() == GetS || ev->getCmd() == GetSEx || ev->getCmd() == GetX) { break; } @@ -313,7 +313,7 @@ bool MSHR::insertInv(Addr baseAddr, mshrType entry, bool inProgress) { }*/ if (inProgress && map_[baseAddr].mshrQueue.size() > 0) it++; map_[baseAddr].mshrQueue.insert(it, entry); - if (entry.elem.type() == typeid(MemEvent*)) size_++; + if (entry.elem.isEvent()) size_++; //printTable(); return true; } @@ -328,8 +328,8 @@ MemEvent* MSHR::getOldestRequest() const { MemEvent *ev = NULL; for ( mshrTable::const_iterator it = map_.begin() ; it != map_.end() ; ++it ) { for ( vector::const_iterator jt = (it->second).mshrQueue.begin() ; jt != (it->second).mshrQueue.end() ; jt++ ) { - if ( jt->elem.type() == typeid(MemEvent*) ) { - MemEvent *me = boost::get(jt->elem); + if ( jt->elem.isEvent() ) { + MemEvent *me = (jt->elem).getEvent(); if ( !ev || ( me->getInitializationTime() < ev->getInitializationTime() ) ) { ev = me; } @@ -366,9 +366,9 @@ vector MSHR::removeAll(Addr baseAddr) { int trueSize = 0; int prefetches = 0; for (vector::iterator it = res.begin(); it != res.end(); it++) { - if ((*it).elem.type() == typeid(MemEvent*)) { + if ((*it).elem.isEvent()) { trueSize++; - MemEvent * ev = boost::get(it->elem); + MemEvent * ev = (it->elem).getEvent(); if (ev->isPrefetch()) prefetches++; } } @@ -390,11 +390,11 @@ MemEvent* MSHR::removeFront(Addr baseAddr) { // d2_->fatal(CALL_INFO,-1, "%s (MSHR), Error: no front entry to remove in mshr for addr = 0x%" PRIx64 "\n", ownerName_.c_str(), baseAddr); //} // - // if (it->second.front().elem.type() != typeid(MemEvent*)) { + // if (it->second.front().elem.isAddr()) { // d2_->fatal(CALL_INFO,-1, "%s (MSHR), Error: front entry in mshr is not of type MemEvent. Addr = 0x%" PRIx64 "\n", ownerName_.c_str(), baseAddr); // } - MemEvent* ret = boost::get((it->second).mshrQueue.front().elem); + MemEvent* ret = ((it->second).mshrQueue.front().elem).getEvent(); if (ret->isPrefetch()) prefetchCount_--; @@ -487,12 +487,12 @@ void MSHR::printTable() { vector entries = (it->second).mshrQueue; d_->debug(_L9_, "MSHR: Addr = 0x%" PRIx64 "\n", (it->first)); for (vector::iterator it2 = entries.begin(); it2 != entries.end(); it2++) { - if (it2->elem.type() != typeid(MemEvent*)) { - Addr ptr = boost::get(it2->elem); + if (it2->elem.isAddr()) { + Addr ptr = (it2->elem).getAddr(); d_->debug(_L9_, "\t0x%" PRIx64 "\n", ptr); } else { - MemEvent * ev = boost::get(it2->elem); + MemEvent * ev = (it2->elem).getEvent(); d_->debug(_L9_, "\t%s, %s\n", ev->getSrc().c_str(), CommandString[ev->getCmd()]); } } diff --git a/src/sst/elements/memHierarchy/mshr.h b/src/sst/elements/memHierarchy/mshr.h index e617607cee..05e004306d 100644 --- a/src/sst/elements/memHierarchy/mshr.h +++ b/src/sst/elements/memHierarchy/mshr.h @@ -27,15 +27,36 @@ #include #include #include -#include namespace SST { namespace MemHierarchy { using namespace std; +// Specific version of variant class to replace boost::variant + +class variant_lite { + union { + Addr addr; + MemEvent* event; + } data; + bool _isAddr; + +public: + variant_lite(Addr a) {data.addr = a; _isAddr = true; } + variant_lite(MemEvent* ev) {data.event = ev; _isAddr = false; } + + Addr getAddr() const { return data.addr; } + MemEvent* getEvent() const { return data.event; } + + bool isAddr() const { return _isAddr; } + bool isEvent() const { return !_isAddr; } + +}; + /* MSHRs hold both events and pointers to events (e.g., the address of an event to replay when the current event resolves) */ struct mshrType { - boost::variant elem; + variant_lite elem; + // boost::variant elem; MemEvent * event; mshrType(MemEvent* ev) : elem(ev), event(ev) {} mshrType(Addr addr) : elem(addr) {} From c10d556fefe59e5a4cddedbcb28943e193e9fbaa Mon Sep 17 00:00:00 2001 From: feldergast Date: Tue, 25 Apr 2017 12:29:24 -0600 Subject: [PATCH 2/3] Added missing header file. --- src/sst/elements/memHierarchy/mshr.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sst/elements/memHierarchy/mshr.cc b/src/sst/elements/memHierarchy/mshr.cc index e8ecfbce51..181af5693f 100644 --- a/src/sst/elements/memHierarchy/mshr.cc +++ b/src/sst/elements/memHierarchy/mshr.cc @@ -16,6 +16,8 @@ #include #include "mshr.h" +#include + using namespace SST; using namespace SST::MemHierarchy; From f565f3d73361f4a874f0b17555ed45a66d78f7bc Mon Sep 17 00:00:00 2001 From: feldergast Date: Wed, 26 Apr 2017 10:52:33 -0600 Subject: [PATCH 3/3] Renamed varian_lite class and removed boost from build system. --- src/sst/elements/memHierarchy/Makefile.am | 2 +- src/sst/elements/memHierarchy/configure.m4 | 3 --- src/sst/elements/memHierarchy/mshr.h | 8 ++++---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/sst/elements/memHierarchy/Makefile.am b/src/sst/elements/memHierarchy/Makefile.am index acde518b1c..963a9d2dc5 100644 --- a/src/sst/elements/memHierarchy/Makefile.am +++ b/src/sst/elements/memHierarchy/Makefile.am @@ -3,7 +3,7 @@ # AM_CPPFLAGS = \ - $(BOOST_CPPFLAGS) $(MPI_CPPFLAGS) \ + $(MPI_CPPFLAGS) \ -I$(top_srcdir)/src compdir = $(pkglibdir) diff --git a/src/sst/elements/memHierarchy/configure.m4 b/src/sst/elements/memHierarchy/configure.m4 index d360b607a5..8187682aba 100644 --- a/src/sst/elements/memHierarchy/configure.m4 +++ b/src/sst/elements/memHierarchy/configure.m4 @@ -23,8 +23,5 @@ AC_DEFUN([SST_memHierarchy_CONFIG], [ # Use FlashDIMMSim SST_CHECK_FDSIM([],[],[AC_MSG_ERROR([FlashDIMMSim requested but could not be found])]) - # Check for BOOST - SST_CHECK_BOOST([],[mh_happy="no"]) - AS_IF([test "$mh_happy" = "yes"], [$1], [$2]) ]) diff --git a/src/sst/elements/memHierarchy/mshr.h b/src/sst/elements/memHierarchy/mshr.h index 05e004306d..421701d75d 100644 --- a/src/sst/elements/memHierarchy/mshr.h +++ b/src/sst/elements/memHierarchy/mshr.h @@ -34,7 +34,7 @@ using namespace std; // Specific version of variant class to replace boost::variant -class variant_lite { +class AddrEventVariant { union { Addr addr; MemEvent* event; @@ -42,8 +42,8 @@ class variant_lite { bool _isAddr; public: - variant_lite(Addr a) {data.addr = a; _isAddr = true; } - variant_lite(MemEvent* ev) {data.event = ev; _isAddr = false; } + AddrEventVariant(Addr a) {data.addr = a; _isAddr = true; } + AddrEventVariant(MemEvent* ev) {data.event = ev; _isAddr = false; } Addr getAddr() const { return data.addr; } MemEvent* getEvent() const { return data.event; } @@ -55,7 +55,7 @@ class variant_lite { /* MSHRs hold both events and pointers to events (e.g., the address of an event to replay when the current event resolves) */ struct mshrType { - variant_lite elem; + AddrEventVariant elem; // boost::variant elem; MemEvent * event; mshrType(MemEvent* ev) : elem(ev), event(ev) {}