From f678104dcc3e5c970b871244e18e38f97c0caaa5 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 12 Sep 2017 18:53:26 -0400 Subject: Adding HBM model --- src/gpgpu-sim/dram.cc | 597 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 457 insertions(+), 140 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') 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("rwq",m_config->CL,m_config->CL+1); mrqq = new fifo_pipeline("mrqq",0,2); returnq = new fifo_pipeline("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<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;inbk;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); - - 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; - } - } - - 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++; - } - - 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++; - } + if (bk[i]->mrq) + memory_Pending++; + } + banks_1time += memory_Pending; + if(memory_Pending >0) + banks_acess_total++; + + 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;jnbk;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++; + } + + unsigned int memory_Pending_ready=0; + for (unsigned j=0;jnbk;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++; + /////////////////////////////////////////////////////////////////////////////////// + + 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;inbk;i++) { + unsigned j = (i + prio) % m_config->nbk; + issued_col_cmd = issue_col_command(j); + if(issued_col_cmd) break; + } + for (unsigned i=0;inbk;i++) { + unsigned j = (i + prio) % m_config->nbk; + issued_row_cmd = issue_row_command(j); + if(issued_row_cmd) break; + } + for (unsigned i=0;inbk;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;inbk;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;inbk;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;jnbk;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;jnbk;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,39 +531,231 @@ 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); for (i=0;inbk;i++) { 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); + } +} -- cgit v1.3 From bd45b8f49f35827dfaa7b5273dda85f0c442fe13 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 13 Sep 2017 09:47:38 -0400 Subject: Fixing some typos --- src/gpgpu-sim/dram.cc | 39 ++++++++++++++++++++++----------------- src/gpgpu-sim/dram.h | 1 + 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 352bd58..dcc0a7d 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -304,29 +304,29 @@ void dram_t::cycle() //collect row buffer locality, BLP and other statistics ///////////////////////////////////////////////////////////////////////// - unsigned int memory_Pending=0; + unsigned int memory_pending=0; for (unsigned i=0;inbk;i++) { if (bk[i]->mrq) - memory_Pending++; + memory_pending++; } - banks_1time += memory_Pending; - if(memory_Pending >0) + banks_1time += memory_pending; + if(memory_pending >0) banks_acess_total++; 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;jnbk;j++) { + unsigned read_blp_rw=0; + unsigned write_blp_rw=0; + std::bitset<8> bnkgrp_rw_found; //assume max we have 8 bank groups + + for (unsigned j=0;jnbk;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); + read_blp_rw++; + bnkgrp_rw_found.set(grp); } else if (bk[j]->mrq && (((bk[j]->curr_row == bk[j]->mrq->row) && @@ -334,15 +334,15 @@ void dram_t::cycle() (bk[j]->state == BANK_ACTIVE)))) { memory_pending_rw++; - write_BLP_RW++; - bnkgrp_RW_found.set(grp); + write_blp_rw++; + bnkgrp_rw_found.set(grp); } } banks_time_rw += memory_pending_rw; - bkgrp_parallsim_rw += bnkgrp_RW_found.count(); + 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); + write_to_read_ratio_blp_rw_average += (double)write_blp_rw/(write_blp_rw+read_blp_rw); banks_access_rw_total++; } @@ -441,6 +441,10 @@ void dram_t::cycle() if(issued_col_cmd) issued_total_col++; if(issued_row_cmd) issued_total_row++; + + //Collect some statistics + //check the limitation, see where BW is wasted? + ///////////////////////////////////////////////////////// unsigned int memory_pending_found=0; for (unsigned i=0;inbk;i++) { if (bk[i]->mrq) @@ -463,8 +467,7 @@ void dram_t::cycle() 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) @@ -507,6 +510,8 @@ void dram_t::cycle() else assert(1); + ///////////////////////////////////////////////////////// + // decrements counters once for each time dram_issueCMD is called DEC2ZERO(RRDc); DEC2ZERO(CCDc); diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 0ec5166..331b4f1 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -180,6 +180,7 @@ private: unsigned int n_req; unsigned int max_mrqs_temp; + //some statistics to collect to see where BW is wasted? unsigned wasted_bw_row; unsigned wasted_bw_col; unsigned util_bw; -- cgit v1.3 From a60c4f9f35850195ec353b3a95d9215288996b8b Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 14 Sep 2017 20:15:27 -0400 Subject: changing the DRAM bank indexing policy --- src/gpgpu-sim/dram.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index dcc0a7d..5c1ddab 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -189,11 +189,12 @@ dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_i const addrdec_t &tlx = mf->get_tlx_addr(); if(dram_bnk_indexing_policy == 0) { - int lbank = log2(banks); - bk = tlx.bk ^ (((1< Date: Wed, 25 Oct 2017 13:15:44 -0400 Subject: The commits includes: 1- REEAD/WERITE buffer for DRAM 2- Fixing FETCH_ON_WRITE cahce policy bug --- src/gpgpu-sim/dram.cc | 11 +++++- src/gpgpu-sim/dram.h | 2 +- src/gpgpu-sim/dram_sched.cc | 95 ++++++++++++++++++++++++++++++++++----------- src/gpgpu-sim/dram_sched.h | 12 ++++++ src/gpgpu-sim/gpu-cache.cc | 34 ++++++++++++---- src/gpgpu-sim/gpu-sim.cc | 7 +++- src/gpgpu-sim/gpu-sim.h | 9 +++++ src/gpgpu-sim/l2cache.cc | 29 ++++++++------ src/gpgpu-sim/mem_fetch.cc | 4 +- src/gpgpu-sim/mem_fetch.h | 4 +- 10 files changed, 160 insertions(+), 47 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 5c1ddab..7ed7b6f 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -149,11 +149,18 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m } -bool dram_t::full() const +bool dram_t::full(bool is_write) const { 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; + if(m_config->seperate_write_queue_enabled){ + if(is_write) + return m_frfcfs_scheduler->num_write_pending() >= m_config->gpgpu_frfcfs_dram_write_queue_size; + else + return m_frfcfs_scheduler->num_pending() >= m_config->gpgpu_frfcfs_dram_sched_queue_size; + } + else + return m_frfcfs_scheduler->num_pending() >= m_config->gpgpu_frfcfs_dram_sched_queue_size; } else return mrqq->full(); } diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 331b4f1..29731a7 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -101,7 +101,7 @@ public: dram_t( unsigned int parition_id, const struct memory_config *config, class memory_stats_t *stats, class memory_partition_unit *mp ); - bool full() const; + bool full(bool is_write) const; void print( FILE* simFile ) const; void visualize() const; void print_stat( FILE* simFile ); diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc index 008b5bb..7a140c5 100644 --- a/src/gpgpu-sim/dram_sched.cc +++ b/src/gpgpu-sim/dram_sched.cc @@ -36,6 +36,7 @@ frfcfs_scheduler::frfcfs_scheduler( const memory_config *config, dram_t *dm, mem m_config = config; m_stats = stats; m_num_pending = 0; + m_num_write_pending = 0; m_dram = dm; m_queue = new std::list[m_config->nbk]; m_bins = new std::map::iterator> >[ m_config->nbk ]; @@ -49,15 +50,36 @@ frfcfs_scheduler::frfcfs_scheduler( const memory_config *config, dram_t *dm, mem curr_row_service_time[i] = 0; row_service_timestamp[i] = 0; } + if(m_config->seperate_write_queue_enabled) { + m_write_queue = new std::list[m_config->nbk]; + m_write_bins = new std::map::iterator> >[ m_config->nbk ]; + m_last_write_row = new std::list::iterator>*[ m_config->nbk ]; + + for ( unsigned i=0; i < m_config->nbk; i++ ) { + m_write_queue[i].clear(); + m_write_bins[i].clear(); + m_last_write_row[i] = NULL; + } + } + m_mode = READ_MODE; } void frfcfs_scheduler::add_req( dram_req_t *req ) { - m_num_pending++; - m_queue[req->bk].push_front(req); - std::list::iterator ptr = m_queue[req->bk].begin(); - m_bins[req->bk][req->row].push_front( ptr ); //newest reqs to the front + if(m_config->seperate_write_queue_enabled && req->data->is_write()) { + assert(m_num_write_pending < m_config->gpgpu_frfcfs_dram_write_queue_size); + m_num_write_pending++; + m_write_queue[req->bk].push_front(req); + std::list::iterator ptr = m_write_queue[req->bk].begin(); + m_write_bins[req->bk][req->row].push_front( ptr ); //newest reqs to the front + } else { + assert(m_num_pending < m_config->gpgpu_frfcfs_dram_sched_queue_size); + m_num_pending++; + m_queue[req->bk].push_front(req); + std::list::iterator ptr = m_queue[req->bk].begin(); + m_bins[req->bk][req->row].push_front( ptr ); //newest reqs to the front + } } void frfcfs_scheduler::data_collection(unsigned int bank) @@ -80,21 +102,43 @@ dram_req_t *frfcfs_scheduler::schedule( unsigned bank, unsigned curr_row ) { //row bool rowhit = true; + std::list *m_current_queue = m_queue; + std::map::iterator> > *m_current_bins = m_bins ; + std::list::iterator> **m_current_last_row = m_last_row; + + if(m_config->seperate_write_queue_enabled) { + if(m_mode == READ_MODE && + ((m_num_write_pending >= m_config->write_high_watermark ) + || (m_queue[bank].empty() && !m_write_queue[bank].empty()))) { + m_mode = WRITE_MODE; + } + else if(m_mode == WRITE_MODE && + (( m_num_write_pending < m_config->write_low_watermark ) + || (!m_queue[bank].empty() && m_write_queue[bank].empty()))){ + m_mode = READ_MODE; + } + } + + if(m_mode == WRITE_MODE) { + m_current_queue = m_write_queue; + m_current_bins = m_write_bins ; + m_current_last_row = m_last_write_row; + } - if ( m_last_row[bank] == NULL ) { - if ( m_queue[bank].empty() ) + if ( m_current_last_row[bank] == NULL ) { + if ( m_current_queue[bank].empty() ) return NULL; - std::map::iterator> >::iterator bin_ptr = m_bins[bank].find( curr_row ); - if ( bin_ptr == m_bins[bank].end()) { - dram_req_t *req = m_queue[bank].back(); - bin_ptr = m_bins[bank].find( req->row ); - assert( bin_ptr != m_bins[bank].end() ); // where did the request go??? - m_last_row[bank] = &(bin_ptr->second); + std::map::iterator> >::iterator bin_ptr = m_current_bins[bank].find( curr_row ); + if ( bin_ptr == m_current_bins[bank].end()) { + dram_req_t *req = m_current_queue[bank].back(); + bin_ptr = m_current_bins[bank].find( req->row ); + assert( bin_ptr != m_current_bins[bank].end() ); // where did the request go??? + m_current_last_row[bank] = &(bin_ptr->second); data_collection(bank); rowhit = false; } else { - m_last_row[bank] = &(bin_ptr->second); + m_current_last_row[bank] = &(bin_ptr->second); rowhit = true; } } @@ -103,25 +147,32 @@ dram_req_t *frfcfs_scheduler::schedule( unsigned bank, unsigned curr_row ) if(rowhit) m_dram->hits_num++; - std::list::iterator next = m_last_row[bank]->back(); + std::list::iterator next = m_current_last_row[bank]->back(); dram_req_t *req = (*next); m_stats->concurrent_row_access[m_dram->id][bank]++; m_stats->row_access[m_dram->id][bank]++; - m_last_row[bank]->pop_back(); + m_current_last_row[bank]->pop_back(); - m_queue[bank].erase(next); - if ( m_last_row[bank]->empty() ) { - m_bins[bank].erase( req->row ); - m_last_row[bank] = NULL; + m_current_queue[bank].erase(next); + if ( m_current_last_row[bank]->empty() ) { + m_current_bins[bank].erase( req->row ); + m_current_last_row[bank] = NULL; } #ifdef DEBUG_FAST_IDEAL_SCHED if ( req ) printf("%08u : DRAM(%u) scheduling memory request to bank=%u, row=%u\n", (unsigned)gpu_sim_cycle, m_dram->id, req->bk, req->row ); #endif - assert( req != NULL && m_num_pending != 0 ); - m_num_pending--; + + if(m_config->seperate_write_queue_enabled && req->data->is_write()) { + assert( req != NULL && m_num_write_pending != 0 ); + m_num_write_pending--; + } + else { + assert( req != NULL && m_num_pending != 0 ); + m_num_pending--; + } return req; } @@ -138,7 +189,7 @@ void dram_t::scheduler_frfcfs() { unsigned mrq_latency; frfcfs_scheduler *sched = m_frfcfs_scheduler; - while ( !mrqq->empty() && (!m_config->gpgpu_frfcfs_dram_sched_queue_size || sched->num_pending() < m_config->gpgpu_frfcfs_dram_sched_queue_size)) { + while ( !mrqq->empty() ) { dram_req_t *req = mrqq->pop(); // Power stats diff --git a/src/gpgpu-sim/dram_sched.h b/src/gpgpu-sim/dram_sched.h index 3860f5b..63f5831 100644 --- a/src/gpgpu-sim/dram_sched.h +++ b/src/gpgpu-sim/dram_sched.h @@ -35,6 +35,11 @@ #include #include +enum memory_mode { + READ_MODE = 0, + WRITE_MODE +}; + class frfcfs_scheduler { public: frfcfs_scheduler( const memory_config *config, dram_t *dm, memory_stats_t *stats ); @@ -43,17 +48,24 @@ public: dram_req_t *schedule( unsigned bank, unsigned curr_row ); void print( FILE *fp ); unsigned num_pending() const { return m_num_pending;} + unsigned num_write_pending() const { return m_num_write_pending;} private: const memory_config *m_config; dram_t *m_dram; unsigned m_num_pending; + unsigned m_num_write_pending; std::list *m_queue; std::map::iterator> > *m_bins; std::list::iterator> **m_last_row; unsigned *curr_row_service_time; //one set of variables for each bank. unsigned *row_service_timestamp; //tracks when scheduler began servicing current row + std::list *m_write_queue; + std::map::iterator> > *m_write_bins; + std::list::iterator> **m_last_write_row; + + enum memory_mode m_mode; memory_stats_t *m_stats; }; diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index eadc094..d199cca 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -945,10 +945,9 @@ void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_a mf->set_addr( block_addr ); m_miss_queue.push_back(mf); mf->set_status(m_miss_queue_status,time); - if(wa) - events.push_back(cache_event(WRITE_ALLOCATE_SENT)); - else + if(!wa) events.push_back(cache_event(READ_REQUEST_SENT)); + do_miss = true; } else if(mshr_hit && !mshr_avail) @@ -1087,6 +1086,8 @@ data_cache::wr_miss_wa_naive( new_addr_type addr, send_read_request(addr, block_addr, cache_index, n_mf, time, do_miss, wb, evicted, events, false, true); + events.push_back(cache_event(WRITE_ALLOCATE_SENT)); + if( do_miss ){ // If evicted block is modified and not a write-through // (already modified lower level) @@ -1111,7 +1112,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, { new_addr_type block_addr = m_config.block_addr(addr); - new_addr_type mshr_addr = m_config.block_addr(mf->get_addr()); + new_addr_type mshr_addr = m_config.mshr_addr(mf->get_addr()); if(mf->get_access_byte_mask().count() == m_config.get_atom_sz()) { @@ -1147,10 +1148,23 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, } else { - if(miss_queue_full(1)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); - return RESERVATION_FAIL; - } + bool mshr_hit = m_mshrs.probe(mshr_addr); + bool mshr_avail = !m_mshrs.full(mshr_addr); + if(miss_queue_full(1) + || (!(mshr_hit && mshr_avail) + && !(!mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size)))) { + //check what is the exactly the failure reason + if(miss_queue_full(1) ) + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + else if(mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + else if (!mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + else + assert(0); + + return RESERVATION_FAIL; + } //prevent Write - Read - Write in pending mshr @@ -1177,8 +1191,10 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), + NULL, mf); + new_addr_type block_addr = m_config.block_addr(addr); bool do_miss = false; bool wb = false; @@ -1191,6 +1207,8 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, cache_block_t* block = m_tag_array->get_block(cache_index); block->set_modified_on_fill(true, mf->get_access_sector_mask()); + events.push_back(cache_event(WRITE_ALLOCATE_SENT)); + if( do_miss ){ // If evicted block is modified and not a write-through // (already modified lower level) diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 470fcf4..7838875 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -201,7 +201,12 @@ void memory_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-dram_bnkgrp_indexing_policy", OPT_UINT32, &dram_bnkgrp_indexing_policy, "dram_bnkgrp_indexing_policy (0 = take higher bits, 1 = take lower bits) (Default = 0)", "0"); - + option_parser_register(opp, "-Seperate_Write_Queue_Enable", OPT_BOOL, &seperate_write_queue_enabled, + "Seperate_Write_Queue_Enable", + "0"); + option_parser_register(opp, "-Write_Queue_Size", OPT_CSTR, &write_queue_size_opt, + "Write_Queue_Size", + "32:28:16"); m_address_mapping.addrdec_setoption(opp); } diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index f379a17..197350b 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -214,6 +214,9 @@ struct memory_config { m_valid = true; icnt_flit_size = 32; // Default 32 + + sscanf(write_queue_size_opt,"%d:%d:%d", + &gpgpu_frfcfs_dram_write_queue_size,&write_high_watermark,&write_low_watermark); } void reg_options(class OptionParser * opp); @@ -274,6 +277,12 @@ struct memory_config { unsigned dram_bnk_indexing_policy; unsigned dram_bnkgrp_indexing_policy; bool dual_bus_interface; + + bool seperate_write_queue_enabled; + char *write_queue_size_opt; + unsigned gpgpu_frfcfs_dram_write_queue_size; + unsigned write_high_watermark; + unsigned write_low_watermark; }; // global counters and flags (please try not to add to this list!!!) diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index f7323c5..cac59f1 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -93,7 +93,9 @@ memory_partition_unit::arbitration_metadata::arbitration_metadata(const struct m m_private_credit_limit = 1; m_shared_credit_limit = config->gpgpu_frfcfs_dram_sched_queue_size + config->gpgpu_dram_return_queue_size - - (config->m_n_sub_partition_per_memory_channel - 1); + - (config->m_n_sub_partition_per_memory_channel - 1); + if(config->seperate_write_queue_enabled ) + m_shared_credit_limit += config->gpgpu_frfcfs_dram_write_queue_size; if (config->gpgpu_frfcfs_dram_sched_queue_size == 0 or config->gpgpu_dram_return_queue_size == 0) { @@ -220,7 +222,8 @@ void memory_partition_unit::dram_cycle() m_dram->cycle(); m_dram->dram_log(SAMPLELOG); - if( !m_dram->full() ) { + // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top(); + //if( !m_dram->full(mf->is_write()) ) { // L2->DRAM queue to DRAM latency queue // Arbitrate among multiple L2 subpartitions int last_issued_partition = m_arbitration_metadata.last_borrower(); @@ -228,6 +231,9 @@ void memory_partition_unit::dram_cycle() int spid = (p + last_issued_partition + 1) % m_config->m_n_sub_partition_per_memory_channel; if (!m_sub_partition[spid]->L2_dram_queue_empty() && can_issue_to_dram(spid)) { mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top(); + if(m_dram->full(mf->is_write()) ) + break; + m_sub_partition[spid]->L2_dram_queue_pop(); MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid); dram_delay_t d; @@ -239,12 +245,13 @@ void memory_partition_unit::dram_cycle() break; // the DRAM should only accept one request per cycle } } - } + //} // DRAM latency queue - if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full() ) { - mem_fetch* mf = m_dram_latency_queue.front().req; - m_dram_latency_queue.pop_front(); + + if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) { + mem_fetch* mf = m_dram_latency_queue.front().req; + m_dram_latency_queue.pop_front(); m_dram->push(mf); } } @@ -343,12 +350,12 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); }else{ - if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE && mf->original_mf) + if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE) { - assert(mf->original_mf); - mf->original_mf->set_reply(); - mf->original_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); - m_L2_icnt_queue->push(mf->original_mf); + assert(mf->original_wr_mf); + mf->original_wr_mf->set_reply(); + mf->original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L2_icnt_queue->push(mf->original_wr_mf); } m_request_tracker.erase(mf); delete mf; diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index b8e918f..c05a693 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -40,7 +40,8 @@ mem_fetch::mem_fetch( const mem_access_t &access, unsigned sid, unsigned tpc, const class memory_config *config, - mem_fetch *m_original_mf) + mem_fetch *m_original_mf, + mem_fetch *m_original_wr_mf) { m_request_uid = sm_next_mf_request_uid++; m_access = access; @@ -63,6 +64,7 @@ mem_fetch::mem_fetch( const mem_access_t &access, m_mem_config = config; icnt_flit_size = config->icnt_flit_size; original_mf = m_original_mf; + original_wr_mf = m_original_wr_mf; } mem_fetch::~mem_fetch() diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index 76e7419..278cf32 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -56,7 +56,8 @@ public: unsigned sid, unsigned tpc, const class memory_config *config, - mem_fetch *original_mf = NULL); + mem_fetch *original_mf = NULL, + mem_fetch *original_wr_mf = NULL); ~mem_fetch(); void set_status( enum mem_fetch_status status, unsigned long long cycle ); @@ -115,6 +116,7 @@ public: unsigned get_num_flits(bool simt_to_mem); mem_fetch* original_mf; + mem_fetch* original_wr_mf; private: // request source information unsigned m_request_uid; -- cgit v1.3 From f23021ad8663636e1103bd75a742480cb6238435 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 27 Oct 2017 22:35:52 -0400 Subject: add more statistics and chaging Pascal config --- configs/Pascal-P102-GDDR5X/gpgpusim.config | 12 +++++++----- src/abstract_hardware_model.cc | 2 +- src/gpgpu-sim/dram.cc | 3 ++- src/gpgpu-sim/dram_sched.cc | 2 ++ src/gpgpu-sim/gpu-cache.cc | 2 ++ src/gpgpu-sim/gpu-sim.cc | 2 +- src/gpgpu-sim/gpu-sim.h | 2 +- src/gpgpu-sim/l2cache.cc | 2 +- src/gpgpu-sim/mem_latency_stat.cc | 17 +++++++++++++---- src/gpgpu-sim/mem_latency_stat.h | 4 ++++ src/gpgpu-sim/shader.cc | 8 ++++---- 11 files changed, 38 insertions(+), 18 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') diff --git a/configs/Pascal-P102-GDDR5X/gpgpusim.config b/configs/Pascal-P102-GDDR5X/gpgpusim.config index 5419c51..e830023 100644 --- a/configs/Pascal-P102-GDDR5X/gpgpusim.config +++ b/configs/Pascal-P102-GDDR5X/gpgpusim.config @@ -59,22 +59,24 @@ # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. # Pascal GP102 has 96KB Shared memory -# Pascal GP102 has 64KB L1 cache +# Pascal GP102 has 24KB L1 cache # The defulat is to disable the L1 cache, unless cache modifieres is used --gpgpu_cache:dl1 S:64:128:6,L:L:m:N:H,A:128:8,8 +-gpgpu_cache:dl1 N:32:128:6,L:L:m:N:H,S:128:8,16 -gpgpu_shmem_size 49152 -gmem_skip_L1D 1 -icnt_flit_size 40 -gpgpu_n_cluster_ejection_buffer_size 32 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache --gpgpu_cache:dl2 S:64:128:16,L:B:m:F:L,A:256:4,4:0,32 +-gpgpu_cache:dl2 S:64:128:16,L:B:m:F:L,A:128:4,16:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 32:32:32:32 +#-gpgpu_flush_l2_cache 1 # 4 KB Inst. -gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 # 48 KB Tex +# this is unused -gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,F:128:4,128:2 # 12 KB Const -gpgpu_const_cache:l1 N:128:64:2,L:R:f:N:L,S:2:64,4 @@ -100,7 +102,7 @@ -gpgpu_shmem_limited_broadcast 0 -gpgpu_shmem_warp_parts 1 # Use Fermi Coalsce arhitetecture which is the same as Pascal --gpgpu_coalesce_arch 20 +-gpgpu_coalesce_arch 61 ## In Pascal, a warp scheduler can issue 2 insts per cycle using 2 diff execution units -gpgpu_max_insn_issue_per_warp 2 @@ -143,7 +145,7 @@ -dram_bnkgrp_indexing_policy 1 #-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 32:28:16 +#-Write_Queue_Size 64:56:32 # Pascal 102 has four schedulers per core -gpgpu_num_sched_per_core 2 diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 51265fd..d2a155c 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -314,7 +314,7 @@ void warp_inst_t::generate_mem_accesses() break; case global_space: case local_space: case param_space_local: - if( m_config->gpgpu_coalesce_arch == 13 || m_config->gpgpu_coalesce_arch == 20) { + if( m_config->gpgpu_coalesce_arch >= 13 && m_config->gpgpu_coalesce_arch <= 62) { if(isatomic()) memory_coalescing_arch_atomic(is_write, access_type); else diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 7ed7b6f..de37f64 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -570,9 +570,10 @@ bool dram_t::issue_col_command(int j) bkgrp[grp]->RTPLc = m_config->tRTPL; issued = true; if(bk[j]->mrq->data->get_access_type() == L2_WR_ALLOC_R) - n_rd_L2_A++; + 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++; diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc index 7a140c5..ac4c827 100644 --- a/src/gpgpu-sim/dram_sched.cc +++ b/src/gpgpu-sim/dram_sched.cc @@ -220,6 +220,8 @@ void dram_t::scheduler_frfcfs() bk[b]->mrq = req; if (m_config->gpgpu_memlatency_stat) { mrq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - bk[b]->mrq->timestamp; + m_stats->tot_mrq_latency += mrq_latency; + m_stats->tot_mrq_num++; bk[b]->mrq->timestamp = gpu_tot_sim_cycle + gpu_sim_cycle; m_stats->mrq_lat_table[LOGB2(mrq_latency)]++; if (mrq_latency > m_stats->max_mrq_latency) { diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index d199cca..32c2bb1 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -333,8 +333,10 @@ void tag_array::fill( unsigned index, unsigned time, mem_fetch* mf) void tag_array::flush() { for (unsigned i=0; i < m_config.get_num_lines(); i++) + if(m_lines[i]->is_modified_line()) { for(unsigned j=0; j < SECTOR_CHUNCK_SIZE; j++) m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)) ; + } } float tag_array::windowed_miss_rate( ) const diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 6179d46..0e06c5c 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1412,7 +1412,7 @@ void gpgpu_sim::cycle() if (mf) { unsigned response_size = mf->get_is_write()?mf->get_ctrl_size():mf->size(); if ( ::icnt_has_buffer( m_shader_config->mem2device(i), response_size ) ) { - if (!mf->get_is_write()) + //if (!mf->get_is_write()) mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle); mf->set_status(IN_ICNT_TO_SHADER,gpu_sim_cycle+gpu_tot_sim_cycle); ::icnt_push( m_shader_config->mem2device(i), mf->get_tpc(), mf, response_size ); diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 52c4643..043fcee 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -199,7 +199,7 @@ struct memory_config { assert(nbkgrp>0 && "Number of bank groups cannot be zero"); tRCDWR = tRCD-(WL+1); tRTW = (CL+(BL/data_command_freq_ratio)+2-WL); - tWTR = (WL+(BL/data_command_freq_ratio)+tCDLR); + tWTR = (WL+(BL/data_command_freq_ratio)+tCDLR); tWTP = (WL+(BL/data_command_freq_ratio)+tWR); dram_atom_size = BL * busW * gpu_n_mem_per_ctrlr; // burst length x bus width x # chips per partition diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index cac59f1..8fbf448 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -628,6 +628,7 @@ std::vector memory_sub_partition::breakdown_request_to_sector_reques void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle ) { if (m_req) { + m_stats->memlatstat_icnt2mem_pop(m_req); std::vector reqs; if(m_config->m_L2_config.m_cache_type == SECTOR) reqs = breakdown_request_to_sector_requests(m_req); @@ -637,7 +638,6 @@ void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle ) for(unsigned i=0; imemlatstat_icnt2mem_pop(req); if( req->istexture() ) { m_icnt_L2_queue->push(req); req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index fde0eff..35d6d84 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -75,6 +75,10 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf max_mf_latency = 0; max_icnt2mem_latency = 0; max_icnt2sh_latency = 0; + tot_icnt2mem_latency = 0; + tot_icnt2sh_latency = 0; + tot_mrq_num = 0; + tot_mrq_latency = 0; memset(mrq_lat_table, 0, sizeof(unsigned)*32); memset(dq_lat_table, 0, sizeof(unsigned)*32); memset(mf_lat_table, 0, sizeof(unsigned)*32); @@ -158,6 +162,7 @@ void memory_stats_t::memlatstat_read_done(mem_fetch *mf) mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk] = mf_latency; unsigned icnt2sh_latency; icnt2sh_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_return_timestamp(); + tot_icnt2sh_latency += icnt2sh_latency; icnt2sh_lat_table[LOGB2(icnt2sh_latency)]++; if (icnt2sh_latency > max_icnt2sh_latency) max_icnt2sh_latency = icnt2sh_latency; @@ -191,6 +196,7 @@ void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf) if (m_memory_config->gpgpu_memlatency_stat) { unsigned icnt2mem_latency; icnt2mem_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_timestamp(); + tot_icnt2mem_latency += icnt2mem_latency; icnt2mem_lat_table[LOGB2(icnt2mem_latency)]++; if (icnt2mem_latency > max_icnt2mem_latency) max_icnt2mem_latency = icnt2mem_latency; @@ -216,14 +222,17 @@ void memory_stats_t::memlatstat_print( unsigned n_mem, unsigned gpu_mem_n_bk ) unsigned max_bank_accesses, min_bank_accesses, max_chip_accesses, min_chip_accesses; if (m_memory_config->gpgpu_memlatency_stat) { + printf("maxmflatency = %d \n", max_mf_latency); + printf("max_icnt2mem_latency = %d \n", max_icnt2mem_latency); printf("maxmrqlatency = %d \n", max_mrq_latency); - printf("maxdqlatency = %d \n", max_dq_latency); - printf("maxmflatency = %d \n", max_mf_latency); + //printf("maxdqlatency = %d \n", max_dq_latency); + printf("max_icnt2sh_latency = %d \n", max_icnt2sh_latency); if (num_mfs) { printf("averagemflatency = %lld \n", mf_total_lat/num_mfs); + printf("avg_icnt2mem_latency = %lld \n", tot_icnt2mem_latency/num_mfs); + printf("avg_mrq_latency = %lld \n", tot_mrq_latency/tot_mrq_num); + printf("avg_icnt2sh_latency = %lld \n", tot_icnt2sh_latency/num_mfs); } - printf("max_icnt2mem_latency = %d \n", max_icnt2mem_latency); - printf("max_icnt2sh_latency = %d \n", max_icnt2sh_latency); printf("mrq_lat_table:"); for (i=0; i< 32; i++) { printf("%d \t", mrq_lat_table[i]); diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h index 4968a3b..5b89202 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -56,6 +56,10 @@ public: unsigned max_dq_latency; unsigned max_mf_latency; unsigned max_icnt2mem_latency; + unsigned long long int tot_icnt2mem_latency; + unsigned long long int tot_icnt2sh_latency; + unsigned long long int tot_mrq_latency; + unsigned long long int tot_mrq_num; unsigned max_icnt2sh_latency; unsigned mrq_lat_table[32]; unsigned dq_lat_table[32]; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index c14e19f..bf482fb 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1458,7 +1458,7 @@ ldst_unit::process_cache_access( cache_t* cache, if( !write_sent ) delete mf; } else if ( status == RESERVATION_FAIL ) { - result = COAL_STALL; + result = BK_CONF; assert( !read_sent ); assert( !write_sent ); delete mf; @@ -1467,8 +1467,8 @@ ldst_unit::process_cache_access( cache_t* cache, //inst.clear_active( access.get_warp_mask() ); // threads in mf writeback when mf returns inst.accessq_pop_back(); } - if( !inst.accessq_empty() ) - result = BK_CONF; + if( !inst.accessq_empty() && result == NO_RC_FAIL) + result = COAL_STALL; return result; } @@ -1563,7 +1563,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea assert( CACHE_UNDEFINED != inst.cache_op ); stall_cond = process_memory_access_queue(m_L1D,inst); } - if( !inst.accessq_empty() ) + if( !inst.accessq_empty() && stall_cond == NO_RC_FAIL) stall_cond = COAL_STALL; if (stall_cond != NO_RC_FAIL) { stall_reason = stall_cond; -- cgit v1.3 From 0b1a646c0ddf5d4db64a2b6fe9dfa30789cf1cd4 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 30 Oct 2017 20:23:51 -0400 Subject: adding new stats and change the PascalP100-HBM config --- configs/Pascal-P100-HBM/config_fermi_islip.icnt | 9 +++++--- configs/Pascal-P100-HBM/gpgpusim.config | 25 ++++++++++++---------- configs/Pascal-P102-GDDR5X/config_fermi_islip.icnt | 3 +++ src/gpgpu-sim/dram.cc | 13 +++++++---- src/gpgpu-sim/dram.h | 4 ++++ src/gpgpu-sim/dram_sched.cc | 21 +++++++++++++----- src/gpgpu-sim/gpu-sim.cc | 4 +++- src/gpgpu-sim/gpu-sim.h | 8 +++++++ 8 files changed, 63 insertions(+), 24 deletions(-) (limited to 'src/gpgpu-sim/dram.cc') diff --git a/configs/Pascal-P100-HBM/config_fermi_islip.icnt b/configs/Pascal-P100-HBM/config_fermi_islip.icnt index a788090..0a73c81 100644 --- a/configs/Pascal-P100-HBM/config_fermi_islip.icnt +++ b/configs/Pascal-P100-HBM/config_fermi_islip.icnt @@ -1,13 +1,13 @@ //21*1 fly with 32 flits per packet under gpgpusim injection mode use_map = 0; -flit_size = 32; +flit_size = 40; // currently we do not use this, see subnets below network_count = 2; // Topology topology = fly; -k = 62; +k = 60; n = 1; // Routing @@ -17,7 +17,10 @@ routing_function = dest_tag; // Flow control num_vcs = 1; -vc_buf_size = 8; +vc_buf_size = 64; +input_buffer_size = 64; +ejection_buffer_size = 64; +boundary_buffer_size = 64; wait_for_tail_credit = 0; diff --git a/configs/Pascal-P100-HBM/gpgpusim.config b/configs/Pascal-P100-HBM/gpgpusim.config index 5b038de..1029194 100644 --- a/configs/Pascal-P100-HBM/gpgpusim.config +++ b/configs/Pascal-P100-HBM/gpgpusim.config @@ -54,13 +54,17 @@ # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. # Pascal GP100 has 64KB Shared memory --gpgpu_cache:dl1 N:64:128:6,L:L:m:N:H,S:128:8,8 +-gpgpu_cache:dl1 S:64:128:6,L:L:m:N:H,A:128:8,32:0,32 -gpgpu_shmem_size 65536 --gmem_skip_L1D 0 +-gmem_skip_L1D 1 +-icnt_flit_size 40 +-gpgpu_n_cluster_ejection_buffer_size 32 -# 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 4MB L2 cache --gpgpu_cache:dl2 S:64:128:16,L:B:m:W:L,A:128:4,4:0,32 +# 32 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 4MB L2 cache +-gpgpu_cache:dl2 S:64:128:16,L:B:m:W:L,A:256:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 +-gpgpu_dram_partition_queues 64:64:64:64 +#-gpgpu_flush_l2_cache 1 # 4 KB Inst. -gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 @@ -89,8 +93,7 @@ -gpgpu_shmem_num_banks 32 -gpgpu_shmem_limited_broadcast 0 -gpgpu_shmem_warp_parts 1 -# Use Fermi Coalscer arhitetecture for now! Need to be canged to pascal Coalscer --gpgpu_coalesce_arch 20 +-gpgpu_coalesce_arch 60 ## In Pascal, a warp scheduler can issue 2 insts per cycle using 2 diff execution units -gpgpu_max_insn_issue_per_warp 2 @@ -123,10 +126,6 @@ -gpgpu_mem_address_mask 1 -gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBBCCC.CCCSSSSS -# GDDR5 timing -#-gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=6:RCD=12:RAS=28:RP=12:RC=40: -# CL=12:WL=4:CDLR=5:WR=12:nbkgrp=4:CCDL=3:RTPL=2" - # HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) # Timing for 1 GHZ # tRRDl and tWTR are missing, need to be added @@ -140,8 +139,12 @@ # HBM has dual bus interface, in which it can issue two col and row commands at a time -dual_bus_interface 1 # select lower bits for bnkgrp to increase bnkgrp parallelism +-dram_bnk_indexing_policy 0 -dram_bnkgrp_indexing_policy 1 +#-Seperate_Write_Queue_Enable 1 +#-Write_Queue_Size 64:56:32 + # Pascal has two schedulers per core -gpgpu_num_sched_per_core 2 # Two Level Scheduler with active and pending pools @@ -158,7 +161,7 @@ -visualizer_enabled 0 # power model configs, disable it untill we create a real energy model for Pascal 100 --power_simulation_enabled 1 +-power_simulation_enabled 0 -gpuwattch_xml_file gpuwattch_gtx480.xml # tracing functionality diff --git a/configs/Pascal-P102-GDDR5X/config_fermi_islip.icnt b/configs/Pascal-P102-GDDR5X/config_fermi_islip.icnt index 58e596d..94b2378 100644 --- a/configs/Pascal-P102-GDDR5X/config_fermi_islip.icnt +++ b/configs/Pascal-P102-GDDR5X/config_fermi_islip.icnt @@ -18,6 +18,9 @@ routing_function = dest_tag; num_vcs = 1; vc_buf_size = 32; +input_buffer_size = 32; +ejection_buffer_size = 32; +boundary_buffer_size = 32; wait_for_tail_credit = 0; diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index de37f64..a57508c 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -52,6 +52,10 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m //rowblp access_num=0; hits_num=0; + read_num=0; + write_num=0; + hits_read_num=0; + hits_write_num=0; banks_1time=0; banks_acess_total=0; banks_acess_total_after=0; @@ -718,6 +722,8 @@ void dram_t::print( FILE* simFile) const fprintf(simFile, "\n------------------------------------------------------------------------\n"); printf("\nRow_Buffer_Locality = %.6f", (float)hits_num / access_num); + printf("\nRow_Buffer_Locality_read = %.6f", (float)hits_read_num / read_num); + printf("\nRow_Buffer_Locality_write = %.6f", (float)hits_write_num / write_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); @@ -735,7 +741,7 @@ void dram_t::print( FILE* simFile) const 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("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); @@ -751,15 +757,14 @@ void dram_t::print( FILE* simFile) const 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("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 ); diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 29731a7..0d4c0e7 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -198,7 +198,11 @@ private: //row locality, BLP and other statistics unsigned long access_num; + unsigned long read_num; + unsigned long write_num; unsigned long long hits_num; + unsigned long long hits_read_num; + unsigned long long hits_write_num; unsigned long long banks_1time; unsigned long long banks_acess_total; unsigned long long banks_acess_total_after; diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc index ac4c827..f754d36 100644 --- a/src/gpgpu-sim/dram_sched.cc +++ b/src/gpgpu-sim/dram_sched.cc @@ -142,14 +142,25 @@ dram_req_t *frfcfs_scheduler::schedule( unsigned bank, unsigned curr_row ) rowhit = true; } } - //rowblp - m_dram->access_num++; - if(rowhit) - m_dram->hits_num++; - std::list::iterator next = m_current_last_row[bank]->back(); dram_req_t *req = (*next); + //rowblp stats + m_dram->access_num++; + bool is_write = req->data->is_write(); + if(is_write) + m_dram->write_num++; + else + m_dram->read_num++; + + if(rowhit) { + m_dram->hits_num++; + if(is_write) + m_dram->hits_write_num++; + else + m_dram->hits_read_num++; + } + m_stats->concurrent_row_access[m_dram->id][bank]++; m_stats->row_access[m_dram->id][bank]++; m_current_last_row[bank]->pop_back(); diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 0e06c5c..11ac5df 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -207,6 +207,9 @@ void memory_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-Write_Queue_Size", OPT_CSTR, &write_queue_size_opt, "Write_Queue_Size", "32:28:16"); + option_parser_register(opp, "-Elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround, + "elimnate_rw_turnaround i.e set tWTR and tRTW = 0", + "0"); option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size, "icnt_flit_size", "32"); @@ -435,7 +438,6 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-gpgpu_flush_l2_cache", OPT_BOOL, &gpgpu_flush_l2_cache, "Flush L2 cache at the end of each kernel call", "0"); - option_parser_register(opp, "-gpgpu_deadlock_detect", OPT_BOOL, &gpu_deadlock_detect, "Stop the simulation at deadlock (1=on (default), 0=off)", "1"); diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 043fcee..c04648c 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -198,8 +198,14 @@ struct memory_config { bk_tag_length = i-1; assert(nbkgrp>0 && "Number of bank groups cannot be zero"); tRCDWR = tRCD-(WL+1); + if(elimnate_rw_turnaround) + { + tRTW = 0; + tWTR = 0; + } else { tRTW = (CL+(BL/data_command_freq_ratio)+2-WL); tWTR = (WL+(BL/data_command_freq_ratio)+tCDLR); + } tWTP = (WL+(BL/data_command_freq_ratio)+tWR); dram_atom_size = BL * busW * gpu_n_mem_per_ctrlr; // burst length x bus width x # chips per partition @@ -266,6 +272,8 @@ struct memory_config { unsigned nbk; + bool elimnate_rw_turnaround; + unsigned data_command_freq_ratio; // frequency ratio between DRAM data bus and command bus (2 for GDDR3, 4 for GDDR5) unsigned dram_atom_size; // number of bytes transferred per read or write command -- cgit v1.3