LAB/GEM5

GEM5, DRAMSim2에 Buffer Hit, Miss 추가

RyoTTa 2021. 6. 21. 18:27
반응형

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;
		}
	}
반응형