summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/dram.cc
diff options
context:
space:
mode:
authorMahmoud <[email protected]>2017-09-12 18:53:26 -0400
committerMahmoud <[email protected]>2017-09-12 18:53:26 -0400
commitf678104dcc3e5c970b871244e18e38f97c0caaa5 (patch)
treedce9c77eace10f87b93b581e435cbe0c17907e02 /src/gpgpu-sim/dram.cc
parentbff1764efb3e1dc91d61190ab61909ac345ec2f0 (diff)
Adding HBM model
Diffstat (limited to 'src/gpgpu-sim/dram.cc')
-rw-r--r--src/gpgpu-sim/dram.cc591
1 files changed, 454 insertions, 137 deletions
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index a0e024b..352bd58 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -49,11 +49,41 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m
m_stats = stats;
m_config = config;
+ //rowblp
+ access_num=0;
+ hits_num=0;
+ banks_1time=0;
+ banks_acess_total=0;
+ banks_acess_total_after=0;
+ banks_time_ready=0;
+ banks_access_ready_total=0;
+ issued_two=0;
+ issued_total=0;
+ issued_total_row=0;
+ issued_total_col=0;
+
CCDc = 0;
RRDc = 0;
RTWc = 0;
WTRc = 0;
+ wasted_bw_row=0;
+ wasted_bw_col=0;
+ util_bw=0;
+ idle_bw=0;
+ RCDc_limit=0;
+ CCDLc_limit=0;
+ CCDLc_limit_alone=0;
+ CCDc_limit=0;
+ WTRc_limit=0;
+ WTRc_limit_alone=0;
+ RCDWRc_limit=0;
+ RTWc_limit=0;
+ RTWc_limit_alone=0;
+ rwq_limit=0;
+ write_to_read_ratio_blp_rw_average=0;
+ bkgrp_parallsim_rw=0;
+
rw = READ; //read mode is default
bkgrp = (bankgrp_t**) calloc(sizeof(bankgrp_t*), m_config->nbkgrp);
@@ -74,12 +104,13 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m
bk[i]->state = BANK_IDLE;
bk[i]->bkgrpindex = i/(m_config->nbk/m_config->nbkgrp);
}
- prio = 0;
+ prio = 0;
+
rwq = new fifo_pipeline<dram_req_t>("rwq",m_config->CL,m_config->CL+1);
mrqq = new fifo_pipeline<dram_req_t>("mrqq",0,2);
returnq = new fifo_pipeline<mem_fetch>("dramreturnq",0,m_config->gpgpu_dram_return_queue_size==0?1024:m_config->gpgpu_dram_return_queue_size);
m_frfcfs_scheduler = NULL;
- if ( m_config->scheduler_type == DRAM_FRFCFS )
+ if ( m_config->scheduler_type == DRAM_FRFCFS)
m_frfcfs_scheduler = new frfcfs_scheduler(m_config,this,stats);
n_cmd = 0;
n_activity = 0;
@@ -88,6 +119,8 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m
n_pre = 0;
n_rd = 0;
n_wr = 0;
+ n_wr_WB=0;
+ n_rd_L2_A=0;
n_req = 0;
max_mrqs_temp = 0;
bwutil = 0;
@@ -113,11 +146,12 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m
mrqq_Dist = StatCreate("mrqq_length",1, queue_limit());
else //queue length is unlimited;
mrqq_Dist = StatCreate("mrqq_length",1,64); //track up to 64 entries
+
}
bool dram_t::full() const
{
- if(m_config->scheduler_type == DRAM_FRFCFS ){
+ if(m_config->scheduler_type == DRAM_FRFCFS){
if(m_config->gpgpu_frfcfs_dram_sched_queue_size == 0 ) return false;
return m_frfcfs_scheduler->num_pending() >= m_config->gpgpu_frfcfs_dram_sched_queue_size;
}
@@ -127,7 +161,7 @@ bool dram_t::full() const
unsigned dram_t::que_length() const
{
unsigned nreqs = 0;
- if (m_config->scheduler_type == DRAM_FRFCFS ) {
+ if (m_config->scheduler_type == DRAM_FRFCFS) {
nreqs = m_frfcfs_scheduler->num_pending();
} else {
nreqs = mrqq->get_length();
@@ -146,7 +180,7 @@ unsigned int dram_t::queue_limit() const
}
-dram_req_t::dram_req_t( class mem_fetch *mf )
+dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy)
{
txbytes = 0;
dqbytes = 0;
@@ -154,7 +188,15 @@ dram_req_t::dram_req_t( class mem_fetch *mf )
const addrdec_t &tlx = mf->get_tlx_addr();
- bk = tlx.bk;
+ if(dram_bnk_indexing_policy == 0) {
+ int lbank = log2(banks);
+ bk = tlx.bk ^ (((1<<lbank)-1) & tlx.row);
+ }
+ else if(dram_bnk_indexing_policy == 1)
+ bk = tlx.bk;
+ else
+ assert(1);
+
row = tlx.row;
col = tlx.col;
nbytes = mf->get_data_size();
@@ -169,14 +211,15 @@ void dram_t::push( class mem_fetch *data )
{
assert(id == data->get_tlx_addr().chip); // Ensure request is in correct memory partition
- dram_req_t *mrq = new dram_req_t(data);
+ dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy);
+
data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
- mrqq->push(mrq);
+ mrqq->push(mrq);
// stats...
n_req += 1;
n_req_partial += 1;
- if ( m_config->scheduler_type == DRAM_FRFCFS ) {
+ if ( m_config->scheduler_type == DRAM_FRFCFS) {
unsigned nreqs = m_frfcfs_scheduler->num_pending();
if ( nreqs > max_mrqs_temp)
max_mrqs_temp = nreqs;
@@ -212,6 +255,7 @@ void dram_t::cycle()
printf("\tDQ: BK%d Row:%03x Col:%03x", cmd->bk, cmd->row, cmd->col + cmd->dqbytes);
#endif
cmd->dqbytes += m_config->dram_atom_size;
+
if (cmd->dqbytes >= cmd->nbytes) {
mem_fetch *data = cmd->data;
data->set_status(IN_PARTITION_MC_RETURNQ,gpu_sim_cycle+gpu_tot_sim_cycle);
@@ -240,7 +284,7 @@ void dram_t::cycle()
printf("Error: Unknown DRAM scheduler type\n");
assert(0);
}
- if ( m_config->scheduler_type == DRAM_FRFCFS ) {
+ if ( m_config->scheduler_type == DRAM_FRFCFS) {
unsigned nreqs = m_frfcfs_scheduler->num_pending();
if ( nreqs > max_mrqs) {
max_mrqs = nreqs;
@@ -258,130 +302,123 @@ void dram_t::cycle()
unsigned k=m_config->nbk;
bool issued = false;
- // check if any bank is ready to issue a new read
+ //collect row buffer locality, BLP and other statistics
+ /////////////////////////////////////////////////////////////////////////
+ unsigned int memory_Pending=0;
for (unsigned i=0;i<m_config->nbk;i++) {
- unsigned j = (i + prio) % m_config->nbk;
- unsigned grp = j>>m_config->bk_tag_length;
- if (bk[j]->mrq) { //if currently servicing a memory request
- bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
- // correct row activated for a READ
- if ( !issued && !CCDc && !bk[j]->RCDc &&
- !(bkgrp[grp]->CCDLc) &&
- (bk[j]->curr_row == bk[j]->mrq->row) &&
- (bk[j]->mrq->rw == READ) && (WTRc == 0 ) &&
- (bk[j]->state == BANK_ACTIVE) &&
- !rwq->full() ) {
- if (rw==WRITE) {
- rw=READ;
- rwq->set_min_length(m_config->CL);
- }
- rwq->push(bk[j]->mrq);
- bk[j]->mrq->txbytes += m_config->dram_atom_size;
- CCDc = m_config->tCCD;
- bkgrp[grp]->CCDLc = m_config->tCCDL;
- RTWc = m_config->tRTW;
- bk[j]->RTPc = m_config->BL/m_config->data_command_freq_ratio;
- bkgrp[grp]->RTPLc = m_config->tRTPL;
- issued = true;
- n_rd++;
- bwutil += m_config->BL/m_config->data_command_freq_ratio;
- bwutil_partial += m_config->BL/m_config->data_command_freq_ratio;
- bk[j]->n_access++;
-#ifdef DRAM_VERIFY
- PRINT_CYCLE=1;
- printf("\tRD Bk:%d Row:%03x Col:%03x \n",
- j, bk[j]->curr_row,
- bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
-#endif
- // transfer done
- if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
- bk[j]->mrq = NULL;
- }
- } else
- // correct row activated for a WRITE
- if ( !issued && !CCDc && !bk[j]->RCDWRc &&
- !(bkgrp[grp]->CCDLc) &&
- (bk[j]->curr_row == bk[j]->mrq->row) &&
- (bk[j]->mrq->rw == WRITE) && (RTWc == 0 ) &&
- (bk[j]->state == BANK_ACTIVE) &&
- !rwq->full() ) {
- if (rw==READ) {
- rw=WRITE;
- rwq->set_min_length(m_config->WL);
- }
- rwq->push(bk[j]->mrq);
+ if (bk[i]->mrq)
+ memory_Pending++;
+ }
+ banks_1time += memory_Pending;
+ if(memory_Pending >0)
+ banks_acess_total++;
- bk[j]->mrq->txbytes += m_config->dram_atom_size;
- CCDc = m_config->tCCD;
- bkgrp[grp]->CCDLc = m_config->tCCDL;
- WTRc = m_config->tWTR;
- bk[j]->WTPc = m_config->tWTP;
- issued = true;
- n_wr++;
- bwutil += m_config->BL/m_config->data_command_freq_ratio;
- bwutil_partial += m_config->BL/m_config->data_command_freq_ratio;
-#ifdef DRAM_VERIFY
- PRINT_CYCLE=1;
- printf("\tWR Bk:%d Row:%03x Col:%03x \n",
- j, bk[j]->curr_row,
- bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
-#endif
- // transfer done
- if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
- bk[j]->mrq = NULL;
- }
- }
+ unsigned int memory_pending_rw=0;
+ unsigned read_BLP_RW=0;
+ unsigned write_BLP_RW=0;
+ std::bitset<8> bnkgrp_RW_found;
+ //bool memory_pending_rw_found=false;
+ for (unsigned j=0;j<m_config->nbk;j++) {
+ unsigned grp = get_bankgrp_number(j);
+ if (bk[j]->mrq && (((bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == READ) &&
+ (bk[j]->state == BANK_ACTIVE))))
+ {
+ memory_pending_rw++;
+ read_BLP_RW++;
+ bnkgrp_RW_found.set(grp);
+ }
+ else if
+ (bk[j]->mrq && (((bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == WRITE) &&
+ (bk[j]->state == BANK_ACTIVE))))
+ {
+ memory_pending_rw++;
+ write_BLP_RW++;
+ bnkgrp_RW_found.set(grp);
+ }
+ }
+ banks_time_rw += memory_pending_rw;
+ bkgrp_parallsim_rw += bnkgrp_RW_found.count();
+ if(memory_pending_rw >0)
+ {
+ write_to_read_ratio_blp_rw_average += (double)write_BLP_RW/(write_BLP_RW+read_BLP_RW);
+ banks_access_rw_total++;
+ }
- else
- // bank is idle
- if ( !issued && !RRDc &&
- (bk[j]->state == BANK_IDLE) &&
- !bk[j]->RPc && !bk[j]->RCc ) {
-#ifdef DRAM_VERIFY
- PRINT_CYCLE=1;
- printf("\tACT BK:%d NewRow:%03x From:%03x \n",
- j,bk[j]->mrq->row,bk[j]->curr_row);
-#endif
- // activate the row with current memory request
- bk[j]->curr_row = bk[j]->mrq->row;
- bk[j]->state = BANK_ACTIVE;
- RRDc = m_config->tRRD;
- bk[j]->RCDc = m_config->tRCD;
- bk[j]->RCDWRc = m_config->tRCDWR;
- bk[j]->RASc = m_config->tRAS;
- bk[j]->RCc = m_config->tRC;
- prio = (j + 1) % m_config->nbk;
- issued = true;
- n_act_partial++;
- n_act++;
- }
+ unsigned int memory_Pending_ready=0;
+ for (unsigned j=0;j<m_config->nbk;j++) {
+ unsigned grp = get_bankgrp_number(j);
+ if (bk[j]->mrq && ((!CCDc && !bk[j]->RCDc &&
+ !(bkgrp[grp]->CCDLc) &&
+ (bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == READ) && (WTRc == 0 ) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ !rwq->full())
+ ||
+ (!CCDc && !bk[j]->RCDWRc &&
+ !(bkgrp[grp]->CCDLc) &&
+ (bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == WRITE) && (RTWc == 0 ) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ !rwq->full())))
+ {
+ memory_Pending_ready++;
+ }
+ }
+ banks_time_ready += memory_Pending_ready;
+ if(memory_Pending_ready >0)
+ banks_access_ready_total++;
+ ///////////////////////////////////////////////////////////////////////////////////
- else
- // different row activated
- if ( (!issued) &&
- (bk[j]->curr_row != bk[j]->mrq->row) &&
- (bk[j]->state == BANK_ACTIVE) &&
- (!bk[j]->RASc && !bk[j]->WTPc &&
- !bk[j]->RTPc &&
- !bkgrp[grp]->RTPLc) ) {
- // make the bank idle again
- bk[j]->state = BANK_IDLE;
- bk[j]->RPc = m_config->tRP;
- prio = (j + 1) % m_config->nbk;
- issued = true;
- n_pre++;
- n_pre_partial++;
-#ifdef DRAM_VERIFY
- PRINT_CYCLE=1;
- printf("\tPRE BK:%d Row:%03x \n", j,bk[j]->curr_row);
-#endif
- }
- } else {
- if (!CCDc && !RRDc && !RTWc && !WTRc && !bk[j]->RCDc && !bk[j]->RASc
- && !bk[j]->RCc && !bk[j]->RPc && !bk[j]->RCDWRc) k--;
- bk[j]->n_idle++;
- }
+ bool issued_col_cmd = false;
+ bool issued_row_cmd = false;
+
+ if(m_config->dual_bus_interface)
+ {
+ //dual bus interface
+ //issue one row command and one column command
+ for (unsigned i=0;i<m_config->nbk;i++) {
+ unsigned j = (i + prio) % m_config->nbk;
+ issued_col_cmd = issue_col_command(j);
+ if(issued_col_cmd) break;
+ }
+ for (unsigned i=0;i<m_config->nbk;i++) {
+ unsigned j = (i + prio) % m_config->nbk;
+ issued_row_cmd = issue_row_command(j);
+ if(issued_row_cmd) break;
+ }
+ for (unsigned i=0;i<m_config->nbk;i++) {
+ unsigned j = (i + prio) % m_config->nbk;
+ if(!bk[j]->mrq) {
+ if (!CCDc && !RRDc && !RTWc && !WTRc && !bk[j]->RCDc && !bk[j]->RASc
+ && !bk[j]->RCc && !bk[j]->RPc && !bk[j]->RCDWRc) k--;
+ bk[j]->n_idle++;
+ }
+ }
+ }
+ else
+ {
+ //single bus interface
+ //issue only one row/column command
+ for (unsigned i=0;i<m_config->nbk;i++) {
+ unsigned j = (i + prio) % m_config->nbk;
+ if(!issued_col_cmd)
+ issued_col_cmd = issue_col_command(j);
+
+ if(!issued_col_cmd && !issued_row_cmd)
+ issued_row_cmd = issue_row_command(j);
+
+ if(!bk[j]->mrq) {
+ if (!CCDc && !RRDc && !RTWc && !WTRc && !bk[j]->RCDc && !bk[j]->RASc
+ && !bk[j]->RCc && !bk[j]->RPc && !bk[j]->RCDWRc) k--;
+ bk[j]->n_idle++;
+ }
+
+ }
}
+
+ issued = issued_row_cmd || issued_col_cmd;
if (!issued) {
n_nop++;
n_nop_partial++;
@@ -395,6 +432,80 @@ void dram_t::cycle()
}
n_cmd++;
n_cmd_partial++;
+ if(issued)
+ {
+ issued_total++;
+ if(issued_col_cmd && issued_row_cmd)
+ issued_two++;
+ }
+ if(issued_col_cmd) issued_total_col++;
+ if(issued_row_cmd) issued_total_row++;
+
+ unsigned int memory_pending_found=0;
+ for (unsigned i=0;i<m_config->nbk;i++) {
+ if (bk[i]->mrq)
+ memory_pending_found++;
+ }
+ if(memory_pending_found>0)
+ banks_acess_total_after++;
+
+ bool memory_pending_rw_found=false;
+ for (unsigned j=0;j<m_config->nbk;j++) {
+ unsigned grp = get_bankgrp_number(j);
+ if (bk[j]->mrq && (((bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == READ) &&
+ (bk[j]->state == BANK_ACTIVE))
+ ||
+ (
+ (bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == WRITE) &&
+ (bk[j]->state == BANK_ACTIVE))))
+ memory_pending_rw_found=true;
+ }
+
+ //Collect some statistics
+ //check the limitation, why BW is wasted?
+ if(issued_col_cmd || CCDc)
+ util_bw++;
+ else if (memory_pending_rw_found)
+ {
+ wasted_bw_col++;
+ for (unsigned j=0;j<m_config->nbk;j++) {
+ unsigned grp = get_bankgrp_number(j);
+ //read
+ if (bk[j]->mrq && (((bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == READ) &&
+ (bk[j]->state == BANK_ACTIVE))))
+ {
+ if(bk[j]->RCDc) RCDc_limit++;
+ if(bkgrp[grp]->CCDLc) CCDLc_limit++;
+ if(WTRc) WTRc_limit++;
+ if(CCDc) CCDc_limit++;
+ if(rwq->full()) rwq_limit++;
+ if(bkgrp[grp]->CCDLc && !WTRc) CCDLc_limit_alone++;
+ if(!bkgrp[grp]->CCDLc && WTRc) WTRc_limit_alone++;
+ }
+ //write
+ else if (bk[j]->mrq && ((bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == WRITE) &&
+ (bk[j]->state == BANK_ACTIVE)))
+ {
+ if(bk[j]->RCDWRc) RCDWRc_limit++;
+ if(bkgrp[grp]->CCDLc) CCDLc_limit++;
+ if(RTWc) RTWc_limit++;
+ if(CCDc) CCDc_limit++;
+ if(rwq->full()) rwq_limit++;
+ if(bkgrp[grp]->CCDLc && !RTWc) CCDLc_limit_alone++;
+ if(!bkgrp[grp]->CCDLc && RTWc) RTWc_limit_alone++;
+ }
+ }
+ }
+ else if (memory_pending_found)
+ wasted_bw_row++;
+ else if (!memory_pending_found)
+ idle_bw++;
+ else
+ assert(1);
// decrements counters once for each time dram_issueCMD is called
DEC2ZERO(RRDc);
@@ -420,26 +531,169 @@ void dram_t::cycle()
#endif
}
+bool dram_t::issue_col_command(int j)
+{
+ bool issued = false;
+ unsigned grp = get_bankgrp_number(j);
+ if (bk[j]->mrq) { //if currently servicing a memory request
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ // correct row activated for a READ
+ if ( !issued && !CCDc && !bk[j]->RCDc &&
+ !(bkgrp[grp]->CCDLc) &&
+ (bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == READ) && (WTRc == 0 ) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ !rwq->full() ) {
+ if (rw==WRITE) {
+ rw=READ;
+ rwq->set_min_length(m_config->CL);
+ }
+ rwq->push(bk[j]->mrq);
+ bk[j]->mrq->txbytes += m_config->dram_atom_size;
+ CCDc = m_config->tCCD;
+ bkgrp[grp]->CCDLc = m_config->tCCDL;
+ RTWc = m_config->tRTW;
+ bk[j]->RTPc = m_config->BL/m_config->data_command_freq_ratio;
+ bkgrp[grp]->RTPLc = m_config->tRTPL;
+ issued = true;
+ if(bk[j]->mrq->data->get_access_type() == L2_WR_ALLOC_R)
+ n_rd_L2_A++;
+ else
+ n_rd++;
+ bwutil += m_config->BL/m_config->data_command_freq_ratio;
+ bwutil_partial += m_config->BL/m_config->data_command_freq_ratio;
+ bk[j]->n_access++;
+
+#ifdef DRAM_VERIFY
+ PRINT_CYCLE=1;
+ printf("\tRD Bk:%d Row:%03x Col:%03x \n",
+ j, bk[j]->curr_row,
+ bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
+#endif
+ // transfer done
+ if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
+ bk[j]->mrq = NULL;
+ }
+ } else
+ // correct row activated for a WRITE
+ if ( !issued && !CCDc && !bk[j]->RCDWRc &&
+ !(bkgrp[grp]->CCDLc) &&
+ (bk[j]->curr_row == bk[j]->mrq->row) &&
+ (bk[j]->mrq->rw == WRITE) && (RTWc == 0 ) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ !rwq->full() ) {
+ if (rw==READ) {
+ rw=WRITE;
+ rwq->set_min_length(m_config->WL);
+ }
+ rwq->push(bk[j]->mrq);
+
+ bk[j]->mrq->txbytes += m_config->dram_atom_size;
+ CCDc = m_config->tCCD;
+ bkgrp[grp]->CCDLc = m_config->tCCDL;
+ WTRc = m_config->tWTR;
+ bk[j]->WTPc = m_config->tWTP;
+ issued = true;
+
+ if(bk[j]->mrq->data->get_access_type() == L2_WRBK_ACC)
+ n_wr_WB++;
+ else
+ n_wr++;
+ bwutil += m_config->BL/m_config->data_command_freq_ratio;
+ bwutil_partial += m_config->BL/m_config->data_command_freq_ratio;
+#ifdef DRAM_VERIFY
+ PRINT_CYCLE=1;
+ printf("\tWR Bk:%d Row:%03x Col:%03x \n",
+ j, bk[j]->curr_row,
+ bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
+#endif
+ // transfer done
+ if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
+ bk[j]->mrq = NULL;
+ }
+ }
+
+ }
+
+ return issued;
+}
+
+bool dram_t::issue_row_command(int j)
+{
+ bool issued = false;
+ unsigned grp = get_bankgrp_number(j);
+ if (bk[j]->mrq) { //if currently servicing a memory request
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ // bank is idle
+ //else
+ if ( !issued && !RRDc &&
+ (bk[j]->state == BANK_IDLE) &&
+ !bk[j]->RPc && !bk[j]->RCc) { //
+#ifdef DRAM_VERIFY
+ PRINT_CYCLE=1;
+ printf("\tACT BK:%d NewRow:%03x From:%03x \n",
+ j,bk[j]->mrq->row,bk[j]->curr_row);
+#endif
+ // activate the row with current memory request
+ bk[j]->curr_row = bk[j]->mrq->row;
+ bk[j]->state = BANK_ACTIVE;
+ RRDc = m_config->tRRD;
+ bk[j]->RCDc = m_config->tRCD;
+ bk[j]->RCDWRc = m_config->tRCDWR;
+ bk[j]->RASc = m_config->tRAS;
+ bk[j]->RCc = m_config->tRC;
+ prio = (j + 1) % m_config->nbk;
+ issued = true;
+ n_act_partial++;
+ n_act++;
+ }
+
+ else
+ // different row activated
+ if ( (!issued) &&
+ (bk[j]->curr_row != bk[j]->mrq->row) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ (!bk[j]->RASc && !bk[j]->WTPc &&
+ !bk[j]->RTPc &&
+ !bkgrp[grp]->RTPLc) ) {
+ // make the bank idle again
+ bk[j]->state = BANK_IDLE;
+ bk[j]->RPc = m_config->tRP;
+ prio = (j + 1) % m_config->nbk;
+ issued = true;
+ n_pre++;
+ n_pre_partial++;
+#ifdef DRAM_VERIFY
+ PRINT_CYCLE=1;
+ printf("\tPRE BK:%d Row:%03x \n", j,bk[j]->curr_row);
+#endif
+ }
+ }
+ return issued;
+}
+
+
//if mrq is being serviced by dram, gets popped after CL latency fulfilled
-class mem_fetch* dram_t::return_queue_pop()
+class mem_fetch* dram_t::return_queue_pop()
{
return returnq->pop();
}
-class mem_fetch* dram_t::return_queue_top()
+class mem_fetch* dram_t::return_queue_top()
{
return returnq->top();
}
+
void dram_t::print( FILE* simFile) const
{
unsigned i;
fprintf(simFile,"DRAM[%d]: %d bks, busW=%d BL=%d CL=%d, ",
id, m_config->nbk, m_config->busW, m_config->BL, m_config->CL );
fprintf(simFile,"tRRD=%d tCCD=%d, tRCD=%d tRAS=%d tRP=%d tRC=%d\n",
- m_config->tCCD, m_config->tRRD, m_config->tRCD, m_config->tRAS, m_config->tRP, m_config->tRC );
- fprintf(simFile,"n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_req=%d n_rd=%d n_write=%d bw_util=%.4g\n",
- n_cmd, n_nop, n_act, n_pre, n_req, n_rd, n_wr,
+ m_config->tRRD, m_config->tCCD, m_config->tRCD, m_config->tRAS, m_config->tRP, m_config->tRC );
+ fprintf(simFile,"n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref_event=%d n_req=%d n_rd=%d n_rd_L2_A=%d n_write=%d n_wr_bk=%d bw_util=%.4g\n",
+ n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_rd_L2_A, n_wr, n_wr_WB,
(float)bwutil/n_cmd);
fprintf(simFile,"n_activity=%d dram_eff=%.4g\n",
n_activity, (float)bwutil/n_activity);
@@ -447,12 +701,61 @@ void dram_t::print( FILE* simFile) const
fprintf(simFile, "bk%d: %da %di ",i,bk[i]->n_access,bk[i]->n_idle);
}
fprintf(simFile, "\n");
+ fprintf(simFile, "\n------------------------------------------------------------------------\n");
+
+ printf("\nRow_Buffer_Locality = %.6f", (float)hits_num / access_num);
+ printf("\nBank_Level_Parallism = %.6f", (float)banks_1time / banks_acess_total);
+ printf("\nBank_Level_Parallism_Col = %.6f", (float)banks_time_rw / banks_access_rw_total);
+ printf("\nBank_Level_Parallism_Ready = %.6f", (float)banks_time_ready /banks_access_ready_total);
+ printf("\nwrite_to_read_ratio_blp_rw_average = %.6f", write_to_read_ratio_blp_rw_average /banks_access_rw_total);
+ printf("\nGrpLevelPara = %.6f \n", (float)bkgrp_parallsim_rw /banks_access_rw_total);
+
+ printf("\nbwutil = %.6f \n", (float)bwutil/n_cmd);
+ printf("total_CMD = %d \n", n_cmd);
+ printf("util_bw = %d \n", util_bw);
+ printf("Wasted_Col = %d \n", wasted_bw_col);
+ printf("Wasted_Row %d \n", wasted_bw_row);
+ printf("Idle = %d \n\n", idle_bw);
+
+ printf("RCDc_limit = %d \n", RCDc_limit);
+ printf("RCDWRc_limit = %d \n", RCDWRc_limit);
+ printf("WTRc_limit = %d \n", WTRc_limit);
+ printf("RTWc_limit = %d \n", RTWc_limit);
+ printf("CCDLc_limit %d \n", CCDLc_limit);
+ printf("rwq = %d \n", rwq_limit);
+ printf("CCDLc_limit_alone = %d \n", CCDLc_limit_alone);
+ printf("WTRc_limit_alone = %d \n", WTRc_limit_alone);
+ printf("RTWc_limit_alone = %d \n", RTWc_limit_alone);
+
+ printf("total_CMD = %d \n", n_cmd);
+ printf("n_nop = %d \n", n_nop);
+ printf("Read = %d \n", n_rd);
+ printf("Write = %d \n",n_wr);
+ printf("L2_Alloc = %d \n", n_rd_L2_A);
+ printf("L2_WB = %d \n", n_wr_WB);
+ printf("n_act = %d \n", n_act);
+ printf("n_pre = %d \n", n_pre);
+ printf("n_ref = %d \n", n_ref);
+ printf("n_req = %d \n", n_req );
+ printf("n_req4 = %d \n", n_req*4 );
+ printf("total_req = %d \n\n", n_rd+n_wr+n_rd_L2_A+n_wr_WB);
+
+ printf("issued_total_row = %lu \n", issued_total_row);
+ printf("issued_total_col = %lu \n", issued_total_col);
+ printf("Row_Bus_Util = %.6f \n", (float)issued_total_row / n_cmd);
+ printf("CoL_Bus_Util = %.6f \n", (float)issued_total_col / n_cmd);
+ printf("Either_Row_CoL_Bus_Util %.6f \n", (float)issued_total / n_cmd);
+ printf("Issued_on_Two_Bus_Simul_Util %.6f \n", (float)issued_two /n_cmd);
+ printf("issued_two_Eff = %.6f \n", (float)issued_two /issued_total);
+ printf("queue_avg = %.6f \n\n", (float)ave_mrqs/n_cmd );
+
+ fprintf(simFile, "\n");
fprintf(simFile, "dram_util_bins:");
for (i=0;i<10;i++) fprintf(simFile, " %d", dram_util_bins[i]);
fprintf(simFile, "\ndram_eff_bins:");
for (i=0;i<10;i++) fprintf(simFile, " %d", dram_eff_bins[i]);
fprintf(simFile, "\n");
- if(m_config->scheduler_type== DRAM_FRFCFS)
+ if(m_config->scheduler_type== DRAM_FRFCFS)
fprintf(simFile, "mrqq: max=%d avg=%g\n", max_mrqs, (float)ave_mrqs/n_cmd);
}
@@ -476,8 +779,8 @@ void dram_t::visualize() const
void dram_t::print_stat( FILE* simFile )
{
- fprintf(simFile,"DRAM (%d): n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_req=%d n_rd=%d n_write=%d bw_util=%.4g ",
- id, n_cmd, n_nop, n_act, n_pre, n_req, n_rd, n_wr,
+ fprintf(simFile,"DRAM (%d): n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref=%d n_req=%d n_rd=%d n_write=%d bw_util=%.4g ",
+ id, n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_wr,
(float)bwutil/n_cmd);
fprintf(simFile, "mrqq: %d %.4g mrqsmax=%d ", max_mrqs, (float)ave_mrqs/n_cmd, max_mrqs_temp);
fprintf(simFile, "\n");
@@ -516,6 +819,7 @@ void dram_t::visualizer_print( gzFile visualizer_file )
n_pre_partial = 0;
n_req_partial = 0;
+
// dram access type classification
for (unsigned j = 0; j < m_config->nbk; j++) {
gzprintf(visualizer_file,"dramglobal_acc_r: %u %u %u\n", id, j,
@@ -553,3 +857,16 @@ void dram_t::set_dram_power_stats( unsigned &cmd,
wr = n_wr;
req = n_req;
}
+
+unsigned dram_t::get_bankgrp_number(unsigned i)
+{
+ if(m_config->dram_bnkgrp_indexing_policy == 0) { //higher bits
+ return i>>m_config->bk_tag_length;
+ }
+ else if (m_config->dram_bnkgrp_indexing_policy == 1) { //lower bits
+ return i&((m_config->nbkgrp-1));
+ }
+ else {
+ assert(1);
+ }
+}