diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2007-05-15 19:04:34 -0400 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2007-05-15 19:04:34 -0400 |
commit | c30e615689148c6e5ecd06e86069cba716dec5e0 (patch) | |
tree | 0a75fdbbd7f1c55ab6f358b621896c58b507cb28 | |
parent | bda25c1d5e63a940074eafae09166cebbbddc233 (diff) | |
parent | f487edf146cdcbc3698cb8b496842641d52aba44 (diff) | |
download | gem5-c30e615689148c6e5ecd06e86069cba716dec5e0.tar.xz |
Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/newmem
into zizzer.eecs.umich.edu:/tmp/newmem
--HG--
extra : convert_revision : e4047d458f0ea4ca6c321a7236b01f80ea4efe33
-rw-r--r-- | configs/boot/netperf-stream-udp-client.rcS | 2 | ||||
-rw-r--r-- | configs/common/Options.py | 3 | ||||
-rw-r--r-- | configs/example/fs.py | 1 | ||||
-rw-r--r-- | configs/example/se.py | 11 | ||||
-rw-r--r-- | src/mem/bridge.cc | 44 | ||||
-rw-r--r-- | src/mem/bridge.hh | 51 | ||||
-rw-r--r-- | src/mem/cache/base_cache.cc | 178 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 27 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 14 |
9 files changed, 138 insertions, 193 deletions
diff --git a/configs/boot/netperf-stream-udp-client.rcS b/configs/boot/netperf-stream-udp-client.rcS index 91268ea50..4acb4243a 100644 --- a/configs/boot/netperf-stream-udp-client.rcS +++ b/configs/boot/netperf-stream-udp-client.rcS @@ -23,7 +23,7 @@ netcat -c -l -p 8000 BINARY=/benchmarks/netperf-bin/netperf TEST="UDP_STREAM" -SHORT_ARGS="-l 2 -- -m 4096" +SHORT_ARGS="-l 2 -- -m 16384 -M 16384 -s 262144 -S 262144" #LONG_ARGS="-k16384,0 -K16384,0 -- -m 65536 -M 65536 -s 262144 -S 262144" diff --git a/configs/common/Options.py b/configs/common/Options.py index 69f48dc3b..4f2b317c0 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006 The Regents of The University of Michigan +# Copyright (c) 2006-2007 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -31,6 +31,7 @@ parser.add_option("-d", "--detailed", action="store_true") parser.add_option("-t", "--timing", action="store_true") parser.add_option("-n", "--num_cpus", type="int", default=1) parser.add_option("--caches", action="store_true") +parser.add_option("--l2cache", action="store_true") # Run duration options parser.add_option("-m", "--maxtick", type="int") diff --git a/configs/example/fs.py b/configs/example/fs.py index bd4637e95..76c12bd9e 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -51,7 +51,6 @@ parser.add_option("--kernel", action="store", type="string") parser.add_option("--script", action="store", type="string") # Benchmark options -parser.add_option("--l2cache", action="store_true") parser.add_option("--dual", action="store_true", help="Simulate two systems attached with an ethernet link") parser.add_option("-b", "--benchmark", action="store", type="string", diff --git a/configs/example/se.py b/configs/example/se.py index 0944a030e..b294480f6 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006 The Regents of The University of Michigan +# Copyright (c) 2006-2007 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -104,7 +104,14 @@ for i in xrange(np): if options.caches: system.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), L1Cache(size = '64kB')) - system.cpu[i].connectMemPorts(system.membus) + if options.l2cache: + system.l2 = L2Cache(size='2MB') + system.tol2bus = Bus() + system.l2.cpu_side = system.tol2bus.port + system.l2.mem_side = system.membus.port + system.cpu[i].connectMemPorts(system.tol2bus) + else: + system.cpu[i].connectMemPorts(system.membus) system.cpu[i].workload = process root = Root(system = system) diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index f525ccb48..9509aea38 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -247,8 +247,6 @@ Bridge::BridgePort::trySend() { assert(!sendQueue.empty()); - int pbs = peerBlockSize(); - PacketBuffer *buf = sendQueue.front(); assert(buf->ready <= curTick); @@ -257,11 +255,15 @@ Bridge::BridgePort::trySend() pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set + // Ugly! @todo When multilevel coherence works this will be removed if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && - pkt->result != Packet::Nacked && pkt->getOffset(pbs) && - pkt->getSize() != pbs) { - buf->partialWriteFix(this); - pkt = buf->pkt; + pkt->result != Packet::Nacked) { + PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq, + Packet::Broadcast); + funcPkt->dataStatic(pkt->getPtr<uint8_t>()); + sendFunctional(funcPkt); + pkt->cmd = MemCmd::WriteReq; + delete funcPkt; } DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", @@ -300,7 +302,6 @@ Bridge::BridgePort::trySend() } } else { DPRINTF(BusBridge, " unsuccessful\n"); - buf->undoPartialWriteFix(); inRetry = true; } DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n", @@ -324,32 +325,18 @@ Bridge::BridgePort::recvRetry() Tick Bridge::BridgePort::recvAtomic(PacketPtr pkt) { - int pbs = otherPort->peerBlockSize(); - Tick atomic_delay; // fix partial atomic writes... similar to the timing code that does the - // same - if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && - pkt->getOffset(pbs) && pkt->getSize() != pbs) { - PacketDataPtr data; - data = new uint8_t[pbs]; - PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, - Packet::Broadcast, pbs); + // same... will be removed once our code gets this right + if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite) { - funcPkt->dataStatic(data); + PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq, + Packet::Broadcast); + funcPkt->dataStatic(pkt->getPtr<uint8_t>()); otherPort->sendFunctional(funcPkt); - assert(funcPkt->result == Packet::Success); delete funcPkt; - memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(), - pkt->getSize()); - PacketPtr newPkt = new Packet(pkt->req, MemCmd::WriteInvalidateReq, - Packet::Broadcast, pbs); - pkt->dataDynamicArray(data); - atomic_delay = otherPort->sendAtomic(newPkt); - delete newPkt; - } else { - atomic_delay = otherPort->sendAtomic(pkt); + pkt->cmd = MemCmd::WriteReq; } - return atomic_delay + delay; + return delay + otherPort->sendAtomic(pkt); } /** Function called by the port when the bus is receiving a Functional @@ -431,3 +418,4 @@ CREATE_SIM_OBJECT(Bridge) REGISTER_SIM_OBJECT("Bridge", Bridge) + diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 5951eeb98..a47fe3c1e 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -80,14 +80,10 @@ class Bridge : public MemObject short origSrc; bool expectResponse; - bool partialWriteFixed; - PacketPtr oldPkt; - PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false) : ready(t), pkt(_pkt), origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), - expectResponse(_pkt->needsResponse() && !nack), - partialWriteFixed(false) + expectResponse(_pkt->needsResponse() && !nack) { if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked) @@ -99,52 +95,7 @@ class Bridge : public MemObject assert(pkt->senderState == this); pkt->setDest(origSrc); pkt->senderState = origSenderState; - if (partialWriteFixed) - delete oldPkt; - } - - void partialWriteFix(Port *port) - { - assert(!partialWriteFixed); - assert(expectResponse); - - Addr pbs = port->peerBlockSize(); - Addr blockAddr = pkt->getAddr() & ~(pbs-1); - partialWriteFixed = true; - PacketDataPtr data; - - data = new uint8_t[pbs]; - RequestPtr funcReq = new Request(blockAddr, 4, 0); - PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq, - Packet::Broadcast); - for (int x = 0; x < pbs; x+=4) { - funcReq->setPhys(blockAddr + x, 4, 0); - funcPkt->reinitFromRequest(); - funcPkt->dataStatic(data + x); - port->sendFunctional(funcPkt); - assert(funcPkt->result == Packet::Success); - } - delete funcPkt; - delete funcReq; - - oldPkt = pkt; - memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), - pkt->getSize()); - pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq, - Packet::Broadcast, pbs); - pkt->dataDynamicArray(data); - pkt->senderState = oldPkt->senderState; } - - void undoPartialWriteFix() - { - if (!partialWriteFixed) - return; - delete pkt; - pkt = oldPkt; - partialWriteFixed = false; - } - }; /** diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index ed665dafb..3ed4b84d1 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -134,8 +134,7 @@ BaseCache::CachePort::recvRetry() isCpuSide && cache->doSlaveRequest()) { DPRINTF(CachePort, "%s has more responses/requests\n", name()); - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); - reqCpu->schedule(curTick + 1); + new BaseCache::RequestEvent(this, curTick + 1); } waitingOnRetry = false; } @@ -178,8 +177,7 @@ BaseCache::CachePort::recvRetry() { DPRINTF(CachePort, "%s has more requests\n", name()); //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); - reqCpu->schedule(curTick + 1); + new BaseCache::RequestEvent(this, curTick + 1); } } else @@ -196,8 +194,7 @@ BaseCache::CachePort::recvRetry() { DPRINTF(CachePort, "%s has more requests\n", name()); //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); - reqCpu->schedule(curTick + 1); + new BaseCache::RequestEvent(this, curTick + 1); } } if (waitingOnRetry) DPRINTF(CachePort, "%s STILL Waiting on retry\n", name()); @@ -228,102 +225,109 @@ BaseCache::CachePort::clearBlocked() } } -BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, bool _newResponse) - : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), - newResponse(_newResponse) +BaseCache::RequestEvent::RequestEvent(CachePort *_cachePort, Tick when) + : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort) { - if (!newResponse) - this->setFlags(AutoDelete); - pkt = NULL; + this->setFlags(AutoDelete); + schedule(when); } void -BaseCache::CacheEvent::process() +BaseCache::RequestEvent::process() { - if (!newResponse) - { - if (cachePort->waitingOnRetry) return; - //We have some responses to drain first - if (!cachePort->drainList.empty()) { - DPRINTF(CachePort, "%s trying to drain a response\n", cachePort->name()); - if (cachePort->sendTiming(cachePort->drainList.front())) { - DPRINTF(CachePort, "%s drains a response succesfully\n", cachePort->name()); - cachePort->drainList.pop_front(); - if (!cachePort->drainList.empty() || - !cachePort->isCpuSide && cachePort->cache->doMasterRequest() || - cachePort->isCpuSide && cachePort->cache->doSlaveRequest()) { - - DPRINTF(CachePort, "%s still has outstanding bus reqs\n", cachePort->name()); - this->schedule(curTick + 1); - } - } - else { - cachePort->waitingOnRetry = true; - DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (cachePort->waitingOnRetry) return; + //We have some responses to drain first + if (!cachePort->drainList.empty()) { + DPRINTF(CachePort, "%s trying to drain a response\n", cachePort->name()); + if (cachePort->sendTiming(cachePort->drainList.front())) { + DPRINTF(CachePort, "%s drains a response succesfully\n", cachePort->name()); + cachePort->drainList.pop_front(); + if (!cachePort->drainList.empty() || + !cachePort->isCpuSide && cachePort->cache->doMasterRequest() || + cachePort->isCpuSide && cachePort->cache->doSlaveRequest()) { + + DPRINTF(CachePort, "%s still has outstanding bus reqs\n", cachePort->name()); + this->schedule(curTick + 1); } } - else if (!cachePort->isCpuSide) - { //MSHR - DPRINTF(CachePort, "%s trying to send a MSHR request\n", cachePort->name()); - if (!cachePort->cache->doMasterRequest()) { - //This can happen if I am the owner of a block and see an upgrade - //while the block was in my WB Buffers. I just remove the - //wb and de-assert the masterRequest - return; - } + else { + cachePort->waitingOnRetry = true; + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + } + } + else if (!cachePort->isCpuSide) + { //MSHR + DPRINTF(CachePort, "%s trying to send a MSHR request\n", cachePort->name()); + if (!cachePort->cache->doMasterRequest()) { + //This can happen if I am the owner of a block and see an upgrade + //while the block was in my WB Buffers. I just remove the + //wb and de-assert the masterRequest + return; + } - pkt = cachePort->cache->getPacket(); - MSHR* mshr = (MSHR*) pkt->senderState; - //Copy the packet, it may be modified/destroyed elsewhere - PacketPtr copyPkt = new Packet(*pkt); - copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>()); - mshr->pkt = copyPkt; + PacketPtr pkt = cachePort->cache->getPacket(); + MSHR* mshr = (MSHR*) pkt->senderState; + //Copy the packet, it may be modified/destroyed elsewhere + PacketPtr copyPkt = new Packet(*pkt); + copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>()); + mshr->pkt = copyPkt; - bool success = cachePort->sendTiming(pkt); - DPRINTF(Cache, "Address %x was %s in sending the timing request\n", - pkt->getAddr(), success ? "succesful" : "unsuccesful"); + bool success = cachePort->sendTiming(pkt); + DPRINTF(Cache, "Address %x was %s in sending the timing request\n", + pkt->getAddr(), success ? "succesful" : "unsuccesful"); - cachePort->waitingOnRetry = !success; - if (cachePort->waitingOnRetry) { - DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); - } + cachePort->waitingOnRetry = !success; + if (cachePort->waitingOnRetry) { + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + } - cachePort->cache->sendResult(pkt, mshr, success); - if (success && cachePort->cache->doMasterRequest()) - { - DPRINTF(CachePort, "%s still more MSHR requests to send\n", - cachePort->name()); - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - this->schedule(curTick+1); - } + cachePort->cache->sendResult(pkt, mshr, success); + if (success && cachePort->cache->doMasterRequest()) + { + DPRINTF(CachePort, "%s still more MSHR requests to send\n", + cachePort->name()); + //Still more to issue, rerequest in 1 cycle + this->schedule(curTick+1); } - else + } + else + { + //CSHR + assert(cachePort->cache->doSlaveRequest()); + PacketPtr pkt = cachePort->cache->getCoherencePacket(); + MSHR* cshr = (MSHR*) pkt->senderState; + bool success = cachePort->sendTiming(pkt); + cachePort->cache->sendCoherenceResult(pkt, cshr, success); + cachePort->waitingOnRetry = !success; + if (cachePort->waitingOnRetry) + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (success && cachePort->cache->doSlaveRequest()) { - //CSHR - assert(cachePort->cache->doSlaveRequest()); - pkt = cachePort->cache->getCoherencePacket(); - MSHR* cshr = (MSHR*) pkt->senderState; - bool success = cachePort->sendTiming(pkt); - cachePort->cache->sendCoherenceResult(pkt, cshr, success); - cachePort->waitingOnRetry = !success; - if (cachePort->waitingOnRetry) - DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); - if (success && cachePort->cache->doSlaveRequest()) - { - DPRINTF(CachePort, "%s still more CSHR requests to send\n", - cachePort->name()); - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - this->schedule(curTick+1); - } + DPRINTF(CachePort, "%s still more CSHR requests to send\n", + cachePort->name()); + //Still more to issue, rerequest in 1 cycle + this->schedule(curTick+1); } - return; } - //Else it's a response +} + +const char * +BaseCache::RequestEvent::description() +{ + return "Cache request event"; +} + +BaseCache::ResponseEvent::ResponseEvent(CachePort *_cachePort) + : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort) +{ +} + +void +BaseCache::ResponseEvent::process() +{ assert(cachePort->transmitList.size()); assert(cachePort->transmitList.front().first <= curTick); - pkt = cachePort->transmitList.front().second; + PacketPtr pkt = cachePort->transmitList.front().second; cachePort->transmitList.pop_front(); if (!cachePort->transmitList.empty()) { Tick time = cachePort->transmitList.front().first; @@ -354,9 +358,9 @@ BaseCache::CacheEvent::process() } const char * -BaseCache::CacheEvent::description() +BaseCache::ResponseEvent::description() { - return "BaseCache timing event"; + return "Cache response event"; } void diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index ee871c1c4..e45e36fa0 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -117,13 +117,20 @@ class BaseCache : public MemObject std::list<std::pair<Tick,PacketPtr> > transmitList; }; - struct CacheEvent : public Event + struct RequestEvent : public Event { CachePort *cachePort; - PacketPtr pkt; - bool newResponse; - CacheEvent(CachePort *_cachePort, bool response); + RequestEvent(CachePort *_cachePort, Tick when); + void process(); + const char *description(); + }; + + struct ResponseEvent : public Event + { + CachePort *cachePort; + + ResponseEvent(CachePort *_cachePort); void process(); const char *description(); }; @@ -132,8 +139,8 @@ class BaseCache : public MemObject CachePort *cpuSidePort; CachePort *memSidePort; - CacheEvent *sendEvent; - CacheEvent *memSendEvent; + ResponseEvent *sendEvent; + ResponseEvent *memSendEvent; private: void recvStatusChange(Port::Status status, bool isCpuSide) @@ -432,9 +439,7 @@ class BaseCache : public MemObject { if (!doMasterRequest() && !memSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = - new BaseCache::CacheEvent(memSidePort, false); - reqCpu->schedule(time); + new RequestEvent(memSidePort, time); } uint8_t flag = 1<<cause; masterRequests |= flag; @@ -469,9 +474,7 @@ class BaseCache : public MemObject { if (!doSlaveRequest() && !cpuSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = - new BaseCache::CacheEvent(cpuSidePort, false); - reqCpu->schedule(time); + new RequestEvent(cpuSidePort, time); } uint8_t flag = 1<<cause; slaveRequests |= flag; diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index db488d33d..9b094c1e3 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1146,11 +1146,11 @@ template<class TagStore, class Coherence> Port * Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx) { - if (if_name == "") + if (if_name == "" || if_name == "cpu_side") { if (cpuSidePort == NULL) { cpuSidePort = new CpuSidePort(name() + "-cpu_side_port", this); - sendEvent = new CacheEvent(cpuSidePort, true); + sendEvent = new ResponseEvent(cpuSidePort); } return cpuSidePort; } @@ -1158,20 +1158,12 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx) { return new CpuSidePort(name() + "-cpu_side_funcport", this); } - else if (if_name == "cpu_side") - { - if (cpuSidePort == NULL) { - cpuSidePort = new CpuSidePort(name() + "-cpu_side_port", this); - sendEvent = new CacheEvent(cpuSidePort, true); - } - return cpuSidePort; - } else if (if_name == "mem_side") { if (memSidePort != NULL) panic("Already have a mem side for this cache\n"); memSidePort = new MemSidePort(name() + "-mem_side_port", this); - memSendEvent = new CacheEvent(memSidePort, true); + memSendEvent = new ResponseEvent(memSidePort); return memSidePort; } else panic("Port name %s unrecognized\n", if_name); |