Ivan Pizarro has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/16968
Change subject: mem-cache: Proactive Instruction Fetch Implementation
......................................................................
mem-cache: Proactive Instruction Fetch Implementation
Ferdman, M., Kaynak, C., & Falsafi, B. (2011, December).
Proactive instruction fetch. In Proceedings of the 44th Annual IEEE/ACM
International Symposium on Microarchitecture (pp. 152-162). ACM.
Change-Id: I38c3ab30a94ab279f03e3d5936ce8ed118310c0e
---
M src/cpu/base.cc
M src/cpu/base.hh
M src/cpu/o3/cpu.cc
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/SConscript
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
A src/mem/cache/prefetch/pif.cc
A src/mem/cache/prefetch/pif.hh
9 files changed, 415 insertions(+), 4 deletions(-)
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 30f6baf..1c3269b 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -391,6 +391,7 @@
ppActiveCycles = pmuProbePoint("ActiveCycles");
ppRetiredInsts = pmuProbePoint("RetiredInsts");
+ ppRetiredInstsPC = pmuProbePoint("RetiredInstsPC");
ppRetiredLoads = pmuProbePoint("RetiredLoads");
ppRetiredStores = pmuProbePoint("RetiredStores");
ppRetiredBranches = pmuProbePoint("RetiredBranches");
@@ -417,6 +418,14 @@
}
void
+BaseCPU::probeInstCommitPC(const StaticInstPtr &inst, Addr pc)
+{
+ if (!inst->isMicroop() || inst->isLastMicroop()) {
+ ppRetiredInstsPC->notify(pc);
+ }
+}
+
+void
BaseCPU::regStats()
{
MemObject::regStats();
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 8673d23..f947181 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -490,6 +490,15 @@
*/
virtual void probeInstCommit(const StaticInstPtr &inst);
+ /**
+ * Helper method to trigger PMU probes for a committed
+ * instruction.
+ *
+ * @param inst Instruction that just committed
+ * @param pc PC of the instruction that just committed
+ */
+ virtual void probeInstCommitPC(const StaticInstPtr &inst, Addr pc);
+
protected:
/**
* Helper method to instantiate probe points belonging to this
@@ -509,6 +518,7 @@
* instructions may call notify once for the entire bundle.
*/
ProbePoints::PMUUPtr ppRetiredInsts;
+ ProbePoints::PMUUPtr ppRetiredInstsPC;
/** Retired load instructions */
ProbePoints::PMUUPtr ppRetiredLoads;
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 965ab04..40dee4a 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1624,6 +1624,7 @@
committedOps[tid]++;
probeInstCommit(inst->staticInst);
+ probeInstCommitPC(inst->staticInst, inst->instAddr());
}
template <class Impl>
diff --git a/src/mem/cache/prefetch/Prefetcher.py
b/src/mem/cache/prefetch/Prefetcher.py
index 31d7486..6027335 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -43,6 +43,7 @@
from m5.params import *
from m5.proxy import *
+from m5.objects.BaseCPU import BaseCPU
from m5.objects.ClockedObject import ClockedObject
from m5.objects.IndexingPolicies import *
from m5.objects.ReplacementPolicies import *
@@ -65,6 +66,7 @@
cxx_header = "mem/cache/prefetch/base.hh"
cxx_exports = [
PyBindMethod("addEventProbe"),
+ PyBindMethod("addCPU"),
]
sys = Param.System(Parent.any, "System this prefetcher belongs to")
@@ -90,6 +92,8 @@
def regProbeListeners(self):
for event in self._events:
event.register()
+ for cpu in self._cpus:
+ self.getCCObject().addCPU(cpu.getCCObject())
self.getCCObject().regProbeListeners()
def listenFromProbe(self, simObj, *probeNames):
@@ -99,6 +103,12 @@
raise TypeError("probeNames must have at least one element")
self.addEvent(HWPProbeEvent(self, simObj, *probeNames))
+ _cpus = []
+ def registerCPU(self, simObj):
+ if not isinstance(simObj, BaseCPU):
+ raise TypeError("argument must be a BaseCPU type")
+ self._cpus.append(simObj)
+
class QueuedPrefetcher(BasePrefetcher):
type = "QueuedPrefetcher"
abstract = True
@@ -363,3 +373,16 @@
delay_queue_cycles = Param.Cycles(60,
"Cycles to delay a write in the left RR table from the
delay \
queue")
+
+class PIFPrefetcher(QueuedPrefetcher):
+ type = 'PIFPrefetcher'
+ cxx_class = 'PIFPrefetcher'
+ cxx_header = "mem/cache/prefetch/pif.hh"
+
+ precSpatialRegionBits = Param.Unsigned(1,
+ "Number of preceding addresses in the spatial region")
+ succSpatialRegionBits = Param.Unsigned(2,
+ "Number of subsequent addresses in the spatial region")
+ compactorEntries = Param.Unsigned(2, "Entries in the temp. compactor")
+ streamAddressBufferEntries = Param.Unsigned(7, "Entries in the SAB")
+ historyBufferSize = Param.Unsigned(16, "Entries in the history buffer")
diff --git a/src/mem/cache/prefetch/SConscript
b/src/mem/cache/prefetch/SConscript
index d87b694..d28b9e9 100644
--- a/src/mem/cache/prefetch/SConscript
+++ b/src/mem/cache/prefetch/SConscript
@@ -37,6 +37,7 @@
Source('bop.cc')
Source('delta_correlating_prediction_tables.cc')
Source('irregular_stream_buffer.cc')
+Source('pif.cc')
Source('queued.cc')
Source('signature_path.cc')
Source('signature_path_v2.cc')
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 52f5d1a..8417e9e 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -79,11 +79,18 @@
}
}
+void
+BasePrefetcher::PrefetchListenerPC::notify(const Addr& pc)
+{
+ parent.notifyRetiredInst(pc);
+}
+
BasePrefetcher::BasePrefetcher(const BasePrefetcherParams *p)
- : ClockedObject(p), listeners(), cache(nullptr),
blkSize(p->block_size),
- lBlkSize(floorLog2(blkSize)), onMiss(p->on_miss), onRead(p->on_read),
- onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst),
- masterId(p->sys->getMasterId(this)),
pageBytes(p->sys->getPageBytes()),
+ : ClockedObject(p), listeners(), listenersPC(), cache(nullptr),
+ blkSize(p->block_size), lBlkSize(floorLog2(blkSize)),
onMiss(p->on_miss),
+ onRead(p->on_read), onWrite(p->on_write), onData(p->on_data),
+ onInst(p->on_inst), masterId(p->sys->getMasterId(this)),
+ pageBytes(p->sys->getPageBytes()),
prefetchOnAccess(p->prefetch_on_access),
useVirtualAddresses(p->use_virtual_addresses), issuedPrefetches(0),
usefulPrefetches(0)
@@ -233,6 +240,14 @@
listeners.push_back(new PrefetchListener(*this, pm, "Hit"));
}
}
+
+ if (!cpus.empty()) {
+ for (auto& cpu : cpus) {
+ ProbeManager *pm(cpu->getProbeManager());
+ listenersPC.push_back(new PrefetchListenerPC(*this, pm,
+ "RetiredInstsPC"));
+ }
+ }
}
void
@@ -241,3 +256,9 @@
ProbeManager *pm(obj->getProbeManager());
listeners.push_back(new PrefetchListener(*this, pm, name));
}
+
+void
+BasePrefetcher::addCPU(BaseCPU *cpu)
+{
+ cpus.push_back(cpu);
+}
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 4df8428..ee42656 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -53,6 +53,7 @@
#include "base/statistics.hh"
#include "base/types.hh"
+#include "cpu/base.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
#include "sim/clocked_object.hh"
@@ -76,7 +77,20 @@
bool isFill;
};
+ class PrefetchListenerPC : public ProbeListenerArgBase<Addr>
+ {
+ public:
+ PrefetchListenerPC(BasePrefetcher &_parent, ProbeManager *pm,
+ const std::string &name)
+ : ProbeListenerArgBase(pm, name),
+ parent(_parent) {}
+ void notify(const Addr& pc) override;
+ protected:
+ BasePrefetcher &parent;
+ };
+
std::vector<PrefetchListener *> listeners;
+ std::vector<PrefetchListenerPC *> listenersPC;
public:
@@ -240,6 +254,9 @@
/** Total prefetches that has been useful */
uint64_t usefulPrefetches;
+ /** Registered cpus */
+ std::list<BaseCPU*> cpus;
+
public:
BasePrefetcher(const BasePrefetcherParams *p);
@@ -258,6 +275,10 @@
virtual void notifyFill(const PacketPtr &pkt)
{}
+ /** Notify prefetcher of instruction retired */
+ virtual void notifyRetiredInst(const Addr pc)
+ {}
+
virtual PacketPtr getPacket() = 0;
virtual Tick nextPrefetchReadyTime() const = 0;
@@ -284,5 +305,10 @@
* @param name The probe name
*/
void addEventProbe(SimObject *obj, const char *name);
+
+ /**
+ * TODO
+ */
+ void addCPU(BaseCPU *cpu);
};
#endif //__MEM_CACHE_PREFETCH_BASE_HH__
diff --git a/src/mem/cache/prefetch/pif.cc b/src/mem/cache/prefetch/pif.cc
new file mode 100644
index 0000000..e18bee8
--- /dev/null
+++ b/src/mem/cache/prefetch/pif.cc
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2019 Metempsy Technology Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ivan Pizarro
+ */
+
+#include "mem/cache/prefetch/pif.hh"
+
+#include "debug/HWPrefetch.hh"
+#include "params/PIFPrefetcher.hh"
+
+PIFPrefetcher::PIFPrefetcher(const PIFPrefetcherParams *p)
+ : QueuedPrefetcher(p),
+ precSize(p->precSpatialRegionBits),
+ succSize(p->succSpatialRegionBits),
+ maxCompactorEntries(p->compactorEntries),
+ maxStreamAddressBufferEntries(p->streamAddressBufferEntries),
+ historyBuffer(p->historyBufferSize),
+ historyBufferTail(0)
+{
+}
+
+PIFPrefetcher::CompactorEntry::CompactorEntry(Addr addr,
+ unsigned int prec_size, unsigned int succ_size)
+{
+ trigger = addr;
+ prec.resize(prec_size, false);
+ succ.resize(succ_size, false);
+}
+
+bool
+PIFPrefetcher::inSameSpatialRegion(Addr pc, const CompactorEntry& ce,
+ unsigned int& blk_distance)
+{
+ const Addr pc_blk = pc >> lBlkSize;
+ const Addr trigger_blk = ce.trigger >> lBlkSize;
+
+ blk_distance = abs(pc_blk - trigger_blk);
+
+ return (pc_blk > trigger_blk) ?
+ (succSize < blk_distance) : (precSize < blk_distance);
+}
+
+void
+PIFPrefetcher::notifyRetiredInst(const Addr pc)
+{
+ // First access to the prefetcher
+ if (temporalCompactor.size() == 0) {
+ spatialCompactor = CompactorEntry(pc, precSize, succSize);
+ } else {
+ // If the PC of the instruction retired is in the same spatial
region
+ // than the last trigger address, update the bit vectors based on
the
+ // distance between them
+ unsigned int blk_distance;
+
+ if (inSameSpatialRegion(pc, spatialCompactor, blk_distance)) {
+ if (pc > spatialCompactor.trigger) {
+ spatialCompactor.succ[blk_distance] = true;
+ } else if (pc < spatialCompactor.trigger) {
+ spatialCompactor.prec[blk_distance] = true;
+ }
+ // If the PC of the instruction retired is outside the latest
spatial
+ // region, check if it matches in any of the regions in the
temporal
+ // compactor and update it to the MRU position
+ } else {
+ bool isInTemporalCompactor = false;
+
+ // Check if the PC is in the temporal compactor
+ for (auto it = temporalCompactor.begin();
+ it != temporalCompactor.end(); it++)
+ {
+ if (inSameSpatialRegion(pc, (*it), blk_distance)) {
+ spatialCompactor = (*it);
+ temporalCompactor.erase(it);
+ isInTemporalCompactor = true;
+ break;
+ }
+ }
+
+ if (temporalCompactor.size() == maxCompactorEntries) {
+ temporalCompactor.pop_front(); // Discard the LRU entry
+ }
+
+ temporalCompactor.push_back(spatialCompactor);
+
+ if (historyBufferTail == historyBuffer.size()) {
+ historyBufferTail = 0;
+ }
+
+ // If the compactor entry is neither the spatial or can't be
+ // found in the temporal compactor, reset the spatial compactor
+ // updating the trigger address and resetting the vector bits
+ if (!isInTemporalCompactor) {
+ // Insert the spatial entry into the history buffer and
update
+ // the 'index' table to point to the new entry
+ historyBuffer[historyBufferTail] = spatialCompactor;
+
+ index.insert(std::pair<Addr, unsigned int>(
+ spatialCompactor.trigger,
historyBufferTail));
+
+ historyBufferTail++;
+
+ // Reset the spatial compactor fields with the new address
+ spatialCompactor = CompactorEntry(pc, precSize, succSize);
+ }
+ }
+ }
+}
+
+void
+PIFPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
+ std::vector<AddrPriority> &addresses)
+{
+ const Addr addr = pfi.getAddr();
+
+ // Check if a valid entry in the 'index' table is found and allocate a
new
+ // active prediction stream
+ const auto index_it = index.find(addr);
+
+ if (index_it != index.end()) {
+ // Trigger address from the 'index' table and index to the history
+ // buffer
+ const unsigned int hb_entry = (*index_it).second;
+
+ // Track the block in the Stream Address Buffer
+ if (streamAddressBuffer.size() == maxStreamAddressBufferEntries) {
+ streamAddressBuffer.pop_front();
+ }
+
+ streamAddressBuffer.push_back(&historyBuffer[hb_entry]);
+
+ // Calculate the addresses of the instruction blocks that are
encoded
+ // by the bit vector and issue prefetch requests for these
addresses.
+ // Predictions are made by traversing the bit vector from left to
right
+ // as this typically predicts the accesses in the order they will
be
+ // issued in the core.
+ //
+ // Before queueing the prefetch, first probe the cache to confirm
that
+ // the block is not present in the cache.
+ const Addr trigger_blk = (*index_it).first >> lBlkSize;
+
+ for (int i = streamAddressBuffer.back()->prec.size()-1; i >= 0;
i--) {
+ bool prec = streamAddressBuffer.back()->prec[i];
+ // Address from the preceding blocks to issue a prefetch
+ const Addr prec_addr = (trigger_blk - i) << lBlkSize;
+ if (prec && !inCache(prec_addr, pfi.isSecure())) {
+ addresses.push_back(AddrPriority(prec_addr, 0));
+ }
+ }
+ for (int i = 0; i < streamAddressBuffer.back()->succ.size(); i++) {
+ bool succ = streamAddressBuffer.back()->succ[i];
+ // Address from the succeding blocks to issue a prefetch
+ const Addr succ_addr = (trigger_blk + i) << lBlkSize;
+ if (succ && !inCache(succ_addr, pfi.isSecure())) {
+ addresses.push_back(AddrPriority(succ_addr, 0));
+ }
+ }
+ }
+}
+
+PIFPrefetcher*
+PIFPrefetcherParams::create()
+{
+ return new PIFPrefetcher(this);
+}
diff --git a/src/mem/cache/prefetch/pif.hh b/src/mem/cache/prefetch/pif.hh
new file mode 100644
index 0000000..b5263cf
--- /dev/null
+++ b/src/mem/cache/prefetch/pif.hh
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2019 Metempsy Technology Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ivan Pizarro
+ */
+
+/** Implementation of the 'Proactive Instruction Fetch' prefetcher
+ * Reference:
+ * Ferdman, M., Kaynak, C., & Falsafi, B. (2011, December).
+ * Proactive instruction fetch.
+ * In Proceedings of the 44th Annual IEEE/ACM International Symposium
+ * on Microarchitecture (pp. 152-162). ACM.
+ */
+
+#ifndef __MEM_CACHE_PREFETCH_PIF_HH__
+#define __MEM_CACHE_PREFETCH_PIF_HH__
+
+#include <deque>
+
+#include "mem/cache/prefetch/queued.hh"
+
+struct PIFPrefetcherParams;
+
+class PIFPrefetcher : public QueuedPrefetcher
+{
+ private:
+
+ /** Number of preceding and subsequent spatial addresses to
compact */
+ const unsigned int precSize;
+ const unsigned int succSize;
+ /** Number of entries used for the temporal compactor */
+ const unsigned int maxCompactorEntries;
+ /** Max number of entries to be used in the Stream Address Buffer
*/
+ const unsigned int maxStreamAddressBufferEntries;
+
+ /**
+ * The compactor tracks retired instructions addresses, leveraging
the
+ * spatial and temporal locality among instructions for
compaction. It
+ *comprises the spatial and temporal compaction mechanisms.
+ *
+ * Taking advantage of the spatial locality across instruction
blocks,
+ * the spatial compactor combines instruction-block addresses that
fall
+ * within a 'spatial region', a group of adjacent instruction
blocks.
+ * When an instruction outside the current spatial region retires,
the
+ * existing spatial region is sent to the temporal compactor.
+ *
+ * The temporal compactor tracks a small number of the
+ * most-recently-observed spatial region records.
+ */
+ struct CompactorEntry {
+ Addr trigger;
+ std::vector<bool> prec;
+ std::vector<bool> succ;
+ CompactorEntry() {}
+ CompactorEntry(Addr, unsigned int, unsigned int);
+ };
+
+ CompactorEntry spatialCompactor;
+ std::deque<CompactorEntry> temporalCompactor;
+
+ /**
+ * History buffer is a circular buffer that stores the sequence of
+ * retired instructions in FIFO order.
+ */
+ std::vector<CompactorEntry> historyBuffer;
+ unsigned int historyBufferTail;
+
+ /**
+ * The index table is a small cache-like structure that facilitates
+ * fast search of the history buffer.
+ */
+ std::map<Addr, unsigned int> index;
+
+ /**
+ * A Stream Address Buffer (SAB) tracks a window of consecutive
+ * spatial regions. The SAB mantains a pointer to the sequence in
the
+ * history buffer, initiallly set to the pointer taken from the
index
+ * table
+ */
+ std::deque<CompactorEntry*> streamAddressBuffer;
+
+ /**
+ * Checks if a given address is in the same defined spatial region
as
+ * the compactor entry.
+ * @param addr Address to check if it's inside the spatial region
+ * @param ce Compactor entry defining the spatial region
+ * @param blk_distance Distance between the trigger and the addr
+ * @return TRUE if they are in the same spatial region, FALSE
otherwise
+ */
+ bool inSameSpatialRegion(Addr addr, const CompactorEntry& ce,
+ unsigned int& blk_distance);
+
+ /**
+ * Updates the prefetcher structures upon an instruction retired
+ * @param pc PC of the instruction being retired
+ */
+ void notifyRetiredInst(const Addr pc) override;
+
+ public:
+ PIFPrefetcher(const PIFPrefetcherParams *p);
+ ~PIFPrefetcher() {}
+
+ void calculatePrefetch(const PrefetchInfo &pfi,
+ std::vector<AddrPriority> &addresses);
+};
+
+#endif // __MEM_CACHE_PREFETCH_PIF_HH__
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/16968
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I38c3ab30a94ab279f03e3d5936ce8ed118310c0e
Gerrit-Change-Number: 16968
Gerrit-PatchSet: 1
Gerrit-Owner: Ivan Pizarro <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev