Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/newmem

into  zizzer.eecs.umich.edu:/tmp/newmem

--HG--
extra : convert_revision : e4047d458f0ea4ca6c321a7236b01f80ea4efe33
This commit is contained in:
Ali Saidi 2007-05-15 19:04:34 -04:00
commit c30e615689
9 changed files with 143 additions and 198 deletions

View file

@ -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"

View file

@ -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")

View file

@ -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",

View file

@ -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)

View file

@ -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)

View file

@ -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;
}
};
/**

View file

@ -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()) {
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());
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;
}
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");
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);
}
else {
cachePort->waitingOnRetry = true;
DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name());
}
else
{
//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);
}
}
return;
}
//Else it's a response
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;
}
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");
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
this->schedule(curTick+1);
}
}
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())
{
DPRINTF(CachePort, "%s still more CSHR requests to send\n",
cachePort->name());
//Still more to issue, rerequest in 1 cycle
this->schedule(curTick+1);
}
}
}
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

View file

@ -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;

View file

@ -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);