반응형
GEM5에 DRAMSim2 설치는 아래와 같이 한다.
Follow these steps to get DRAMSim2 as part of gem5
1. Download DRAMSim2
1.1 Go to ext/dramsim2 (this directory)
1.2 Clone DRAMSim2: git clone git://github.com/dramninjasUMD/DRAMSim2.git
2. Compile gem5
2.1 Business as usual
3. Run gem5 with DRAMSim2
3.1 Use --mem-type=dramsim2 and set the device and system configuration
$ vim ./gem5/ext/dramsim2/DRAMSim2/BankState.h
public:
//Fields
CurrentBankState currentBankState;
unsigned openRowAddress;
uint64_t nextRead;
uint64_t nextWrite;
uint64_t nextActivate;
uint64_t nextPrecharge;
uint64_t nextPowerUp;
BusPacketType lastCommand;
unsigned stateChangeCountdown;
//Functions
BankState(ostream &dramsim_log_);
void print();
위의 코드를 아래와같이 수정한다.
public:
//Fields
CurrentBankState currentBankState;
unsigned openRowAddress;
uint64_t nextRead;
uint64_t nextWrite;
uint64_t nextActivate;
uint64_t nextPrecharge;
uint64_t nextPowerUp;
BusPacketType lastCommand;
unsigned stateChangeCountdown;
#ifdef RYOTTA
unsigned lastOpenRow;
unsigned long rowBufferAccessTimes =0;
unsigned long rowBufferHitTimes=0;
unsigned long rowBufferMissTimes=0;
unsigned long rowBufferWriteHits=0;
unsigned long rowBufferWriteMiss=0;
unsigned long rowBufferReadHits=0;
unsigned long rowBufferReadMiss=0;
#endif
//Functions
BankState(ostream &dramsim_log_);
void print();
$ vim ./gem5/ext/dramsim2/DRAMSim2/Rank.h
public:
//functions
Rank(ostream &dramsim_log_);
virtual ~Rank();
void receiveFromBus(BusPacket *packet);
void attachMemoryController(MemoryController *mc);
위의 코드를 아래와같이 수정한다.
public:
//functions
Rank(ostream &dramsim_log_);
virtual ~Rank();
void receiveFromBus(BusPacket *packet, unsigned long *BufferWriteHits,
unsigned long *BufferWriteMiss,
unsigned long *BufferReadHits,
unsigned long *BufferReadMiss,
unsigned long *BufferAccess);
void attachMemoryController(MemoryController *mc);
$ vim ./gem5/ext/dramsim2/DRAMSim2/Rank.cpp
void Rank::receiveFromBus(BusPacket *packet)
{
...
switch (packet->busPacketType)
{
case READ:
//make sure a read is allowed
if (bankStates[packet->bank].currentBankState != RowActive ||
currentClockCycle < bankStates[packet->bank].nextRead ||
packet->row != bankStates[packet->bank].openRowAddress)
....
case WRITE:
//make sure a write is allowed
if (bankStates[packet->bank].currentBankState != RowActive ||
currentClockCycle < bankStates[packet->bank].nextWrite ||
packet->row != bankStates[packet->bank].openRowAddress)
....
}
}
위의 코드를 아래와같이 수정한다.
void Rank::receiveFromBus(BusPacket *packet, unsigned long *BufferWriteHits,
unsigned long *BufferWriteMiss,
unsigned long *BufferReadHits,
unsigned long *BufferReadMiss,
unsigned long *BufferAccess)
{
...
switch (packet->busPacketType)
{
case READ:
#ifdef RYOTTA
++bankStates[packet->bank].rowBufferAccessTimes;
if(packet->row == bankStates[packet->bank].lastOpenRow){
++bankStates[packet->bank].rowBufferHitTimes;
++bankStates[packet->bank].rowBufferReadHits;
(*BufferReadHits)++;
}
else {
++bankStates[packet->bank].rowBufferMissTimes;
++bankStates[packet->bank].rowBufferReadMiss;
(*BufferReadMiss)++;
}
bankStates[packet->bank].lastOpenRow = packet->row;
(*BufferAccess)++;
#endif
//make sure a read is allowed
...
case WRITE:
#ifdef RYOTTA
++bankStates[packet->bank].rowBufferAccessTimes;
if(packet->row == bankStates[packet->bank].lastOpenRow){
++bankStates[packet->bank].rowBufferHitTimes;
++bankStates[packet->bank].rowBufferWriteHits;
(*BufferWriteHits)++;
}
else {
++bankStates[packet->bank].rowBufferMissTimes;
++bankStates[packet->bank].rowBufferWriteMiss;
(*BufferWriteMiss)++;
}
bankStates[packet->bank].lastOpenRow = packet->row;
(*BufferAccess)++;
#endif
//make sure a write is allowed
...
}
}
READ, READ_P, WRITE, WRITE_P에 위와같은 코드를 입력한다.
$ vim ./gem5/ext/dramsim2/DRAMSim2/MemoryController.h
public:
// energy values are per rank -- SST uses these directly, so make these public
vector< uint64_t > backgroundEnergy;
vector< uint64_t > burstEnergy;
vector< uint64_t > actpreEnergy;
vector< uint64_t > refreshEnergy;
위의 코드를 아래와같이 수정한다.
public:
// energy values are per rank -- SST uses these directly, so make these public
vector< uint64_t > backgroundEnergy;
vector< uint64_t > burstEnergy;
vector< uint64_t > actpreEnergy;
vector< uint64_t > refreshEnergy;
#ifdef RYOTTA
vector< unsigned long > BufferWriteHits;
vector< unsigned long > BufferWriteMiss;
vector< unsigned long > BufferReadHits;
vector< unsigned long > BufferReadMiss;
#endif
$ vim ./gem5/ext/dramsim2/DRAMSim2/MemoryController.cpp
//Power related packets
backgroundEnergy = vector <uint64_t >(NUM_RANKS,0);
burstEnergy = vector <uint64_t> (NUM_RANKS,0);
actpreEnergy = vector <uint64_t> (NUM_RANKS,0);
refreshEnergy = vector <uint64_t> (NUM_RANKS,0);
totalEpochLatency = vector<uint64_t> (NUM_RANKS*NUM_BANKS,0);
위의 코드를 아래와같이 수정한다.
//Power related packets
backgroundEnergy = vector <uint64_t >(NUM_RANKS,0);
burstEnergy = vector <uint64_t> (NUM_RANKS,0);
actpreEnergy = vector <uint64_t> (NUM_RANKS,0);
refreshEnergy = vector <uint64_t> (NUM_RANKS,0);
#ifdef RYOTTA
BufferWriteHits = vector <unsigned long >(NUM_RANKS,0);
BufferWriteMiss = vector <unsigned long >(NUM_RANKS,0);
BufferReadHits = vector <unsigned long >(NUM_RANKS,0);
BufferReadMiss = vector <unsigned long >(NUM_RANKS,0);
#endif
totalEpochLatency = vector<uint64_t> (NUM_RANKS*NUM_BANKS,0);
//prints statistics at the end of an epoch or simulation
void MemoryController::printStats(bool finalStats)
{
...
if (finalStats)
{
...
}
....
}
위의 코드를 아래와같이 수정한다.
//prints statistics at the end of an epoch or simulation
void MemoryController::printStats(bool finalStats)
{
...
if (finalStats)
{
...
#ifdef RYOTTA
for(int i=0;i<NUM_RANKS;i++){
printf("%d RANK : BufferAccess %lu\n",i,BufferAccess[i]);
printf("%d RANK : BufferWriteHits %lu\n",i,BufferWriteHits[i]);
printf("%d RANK : BufferWriteMiss %lu\n",i,BufferWriteMiss[i]);
printf("%d RANK : BufferReadHits %lu\n",i,BufferReadHits[i]);
printf("%d RANK : BufferReadMiss %lu\n",i,BufferReadMiss[i]);
}
#endif
...
}
....
}
if (outgoingCmdPacket != NULL)
{
cmdCyclesLeft--;
if (cmdCyclesLeft == 0) //packet is ready to be received by rank
{
(*ranks)[outgoingCmdPacket->rank]->receiveFromBus(outgoingCmdPacket);
outgoingCmdPacket = NULL;
}
}
//check for outgoing data packets and handle countdowns
if (outgoingDataPacket != NULL)
{
dataCyclesLeft--;
if (dataCyclesLeft == 0)
{
//inform upper levels that a write is done
if (parentMemorySystem->WriteDataDone!=NULL)
{
(*parentMemorySystem->WriteDataDone)(parentMemorySystem->systemID,outgoingDataPacket->physicalAddress, currentClockCycle);
}
(*ranks)[outgoingDataPacket->rank]->receiveFromBus(outgoingDataPacket);
outgoingDataPacket=NULL;
}
}
위의 코드를 아래와같이 수정한다.
if (outgoingCmdPacket != NULL)
{
...
(*ranks)[outgoingCmdPacket->rank]->receiveFromBus(outgoingCmdPacket,&(BufferWriteHits[outgoingCmdPacket->rank]),
&(BufferWriteMiss[outgoingCmdPacket->rank]),
&(BufferReadHits[outgoingCmdPacket->rank]),
&(BufferReadMiss[outgoingCmdPacket->rank]),
&(BufferAccess[outgoingCmdPacket->rank]));
outgoingCmdPacket = NULL;
}
}
//check for outgoing data packets and handle countdowns
if (outgoingDataPacket != NULL)
{
...
(*ranks)[outgoingDataPacket->rank]->receiveFromBus(outgoingDataPacket,&(BufferWriteHits[outgoingDataPacket->rank]),
&(BufferWriteMiss[outgoingDataPacket->rank]),
&(BufferReadHits[outgoingDataPacket->rank]),
&(BufferReadMiss[outgoingDataPacket->rank]));
&(BufferAccess[outgoingDataPacket->rank]));
outgoingDataPacket=NULL;
}
}
반응형
'LAB > GEM5' 카테고리의 다른 글
GEM5 v21.2.1.1, L2 private cache, L3 shared cache (1) | 2022.05.12 |
---|---|
GEM5, NVMain V.20.0.3에 맞게 수정 (3) | 2021.08.27 |
GEM5, NVMain FRFCFS MemCon에 WR,RD buffer hit,miss 추가 (0) | 2021.06.11 |
GEM5, NVMain 설치 (2) (0) | 2021.03.17 |
GEM5, NVMain에 L3 Cache 추가 (0) | 2021.03.17 |