diff options
| author | Tor Aamodt <[email protected]> | 2010-10-18 02:43:17 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-10-18 02:43:17 -0800 |
| commit | 87e4da5fc6086c3d0a661af1929255a8cbd728d7 (patch) | |
| tree | a4f40e66f5ca0d6efdf9d51672a1180c8a381170 /src/gpgpu-sim/dram.cc | |
| parent | b577cbcdf229a2c02d1bf8584c6e82be7a14cb33 (diff) | |
Re-designed cache model:
- read only cache model with integrated mshrs (no L1D, yet); new
cache interface should be easily extendable to support texture
cache with latency fifo and separate tag/data arrays, though
this is not yet added (currently tags and data arrays are not
decoupled for texture)
- new partition model using the above
removes all old MSHRs, L1D etc...
passing CUDA 3.1 regression
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7875]
Diffstat (limited to 'src/gpgpu-sim/dram.cc')
| -rw-r--r-- | src/gpgpu-sim/dram.cc | 151 |
1 files changed, 62 insertions, 89 deletions
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 9f79c7e..a1187ec 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -1,5 +1,5 @@ /* - * dram.c + * dram.cc * * Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung, George L. Yuan, * Ivan Sham, Justin Kwong, Dan O'Connor and the @@ -69,6 +69,7 @@ #include "dram.h" #include "mem_latency_stat.h" #include "dram_sched.h" +#include "mem_fetch.h" #ifdef DRAM_VERIFY int PRINT_CYCLE = 0; @@ -98,12 +99,12 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m bk[i]->state = BANK_IDLE; prio = 0; - rwq = new fifo_pipeline<dram_req_t>("rwq",m_config->CL,m_config->CL+1,gpu_sim_cycle); - mrqq = new fifo_pipeline<dram_req_t>("mrqq",0,0,gpu_sim_cycle); - returnq = new fifo_pipeline<mem_fetch>("dramreturnq",0,m_config->gpgpu_dram_sched_queue_size,gpu_sim_cycle); + 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_sched_queue_size); m_fast_ideal_scheduler = NULL; - if ( m_config->scheduler_type == DRAM_IDEAL_FAST ) - m_fast_ideal_scheduler = new ideal_dram_scheduler(m_config,this,stats); + if ( m_config->scheduler_type == DRAM_FRFCFS ) + m_fast_ideal_scheduler = new frfcfs_scheduler(m_config,this,stats); n_cmd = 0; n_activity = 0; n_nop = 0; @@ -137,24 +138,20 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m mrqq_Dist = StatCreate("mrqq_length",1,64); //track up to 64 entries } -int dram_t::full() +bool dram_t::full() const { - int full = 0; - if ( m_config->gpgpu_dram_sched_queue_size == 0 ) return 0; - if ( m_config->scheduler_type == DRAM_IDEAL_FAST ) { - unsigned nreqs = m_fast_ideal_scheduler->num_pending() + mrqq->get_n_element(); - full = (nreqs >= m_config->gpgpu_dram_sched_queue_size); - } else { - full = (mrqq->get_length() >= m_config->gpgpu_dram_sched_queue_size); - } - - return full; + if( m_config->gpgpu_dram_sched_queue_size == 0 ) + return false; + if( m_config->scheduler_type == DRAM_FRFCFS ) + return m_fast_ideal_scheduler->num_pending() >= m_config->gpgpu_dram_sched_queue_size; + else + return mrqq->full(); } -unsigned int dram_t::que_length() const +unsigned dram_t::que_length() const { unsigned nreqs = 0; - if (m_config->scheduler_type == DRAM_IDEAL_FAST ) { + if (m_config->scheduler_type == DRAM_FRFCFS ) { nreqs = m_fast_ideal_scheduler->num_pending(); } else { nreqs = mrqq->get_length(); @@ -195,12 +192,13 @@ dram_req_t::dram_req_t( class mem_fetch *mf ) void dram_t::push( class mem_fetch *data ) { dram_req_t *mrq = new dram_req_t(data); - mrqq->push(mrq,gpu_sim_cycle); + data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mrqq->push(mrq); // stats... n_req += 1; n_req_partial += 1; - if ( m_config->scheduler_type == DRAM_IDEAL_FAST ) { + if ( m_config->scheduler_type == DRAM_FRFCFS ) { unsigned nreqs = m_fast_ideal_scheduler->num_pending(); if ( nreqs > max_mrqs_temp) max_mrqs_temp = nreqs; @@ -215,10 +213,10 @@ void dram_t::scheduler_fifo() if (!mrqq->empty()) { unsigned int bkn; dram_req_t *head_mrqq = mrqq->top(); + head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); bkn = head_mrqq->bk; - if (!bk[bkn]->mrq) { - bk[bkn]->mrq = mrqq->pop(gpu_sim_cycle); - } + if (!bk[bkn]->mrq) + bk[bkn]->mrq = mrqq->pop(); } } @@ -226,23 +224,40 @@ void dram_t::scheduler_fifo() #define DEC2ZERO(x) x = (x)? (x-1) : 0; #define SWAP(a,b) a ^= b; b ^= a; a ^= b; -void dram_t::issueCMD() +void dram_t::cycle() { - unsigned i,j,k; - unsigned char issued; - issued = 0; + + if( !returnq->full() ) { + dram_req_t *cmd = rwq->pop(); + if( cmd ) { +#ifdef DRAM_VIEWCMD + printf("\tDQ: BK%d Row:%03x Col:%03x", cmd->bk, cmd->row, cmd->col + cmd->dqbytes); +#endif + cmd->dqbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; /*16 bytes*/ + if (cmd->dqbytes >= cmd->nbytes) { + mem_fetch *data = cmd->data; + data->set_status(IN_PARTITION_MC_RETURNQ,gpu_sim_cycle+gpu_tot_sim_cycle); + data->set_type(REPLY_DATA); + returnq->push(data); + delete cmd; + } +#ifdef DRAM_VIEWCMD + printf("\n"); +#endif + } + } /* check if the upcoming request is on an idle bank */ /* Should we modify this so that multiple requests are checked? */ switch (m_config->scheduler_type) { case DRAM_FIFO: scheduler_fifo(); break; - case DRAM_IDEAL_FAST: fast_scheduler_ideal(); break; + case DRAM_FRFCFS: fast_scheduler_ideal(); break; default: printf("Error: Unknown DRAM scheduler type\n"); assert(0); } - if ( m_config->scheduler_type == DRAM_IDEAL_FAST ) { + if ( m_config->scheduler_type == DRAM_FRFCFS ) { unsigned nreqs = m_fast_ideal_scheduler->num_pending(); if ( nreqs > max_mrqs) { max_mrqs = nreqs; @@ -256,11 +271,15 @@ void dram_t::issueCMD() ave_mrqs += mrqq->get_length(); ave_mrqs_partial += mrqq->get_length(); } - k=m_config->nbk; + + unsigned k=m_config->nbk; + bool issued = false; + // check if any bank is ready to issue a new read - for (i=0;i<m_config->nbk;i++) { - j = (i + prio) % m_config->nbk; + for (unsigned i=0;i<m_config->nbk;i++) { + unsigned j = (i + prio) % m_config->nbk; 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 && (bk[j]->curr_row == bk[j]->mrq->row) && @@ -269,13 +288,13 @@ void dram_t::issueCMD() !rwq->full() ) { if (rw==WRITE) { rw=READ; - rwq->set_min_length(m_config->CL,gpu_sim_cycle); + rwq->set_min_length(m_config->CL); } - rwq->push(bk[j]->mrq,gpu_sim_cycle); + rwq->push(bk[j]->mrq); bk[j]->mrq->txbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; //16 bytes CCDc = m_config->tCCD; RTWc = m_config->tRTW; - issued = 1; + issued = true; n_rd++; bwutil+= m_config->BL/2; bwutil_partial += m_config->BL/2; @@ -299,13 +318,13 @@ void dram_t::issueCMD() !rwq->full() ) { if (rw==READ) { rw=WRITE; - rwq->set_min_length(m_config->WL,gpu_sim_cycle); + rwq->set_min_length(m_config->WL); } - rwq->push(bk[j]->mrq,gpu_sim_cycle); + rwq->push(bk[j]->mrq); bk[j]->mrq->txbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; /*16 bytes*/ CCDc = m_config->tCCD; - issued = 1; + issued = true; n_wr++; bwutil+=2; bwutil_partial += m_config->BL/2; @@ -340,7 +359,7 @@ void dram_t::issueCMD() bk[j]->RASc = m_config->tRAS; bk[j]->RCc = m_config->tRC; prio = (j + 1) % m_config->nbk; - issued = 1; + issued = true; n_act_partial++; n_act++; } @@ -355,7 +374,7 @@ void dram_t::issueCMD() bk[j]->state = BANK_IDLE; bk[j]->RPc = m_config->tRP; prio = (j + 1) % m_config->nbk; - issued = 1; + issued = true; n_pre++; n_pre_partial++; #ifdef DRAM_VERIFY @@ -388,7 +407,7 @@ void dram_t::issueCMD() DEC2ZERO(CCDc); DEC2ZERO(RTWc); DEC2ZERO(WTRc); - for (j=0;j<m_config->nbk;j++) { + for (unsigned j=0;j<m_config->nbk;j++) { DEC2ZERO(bk[j]->RCDc); DEC2ZERO(bk[j]->RASc); DEC2ZERO(bk[j]->RCc); @@ -404,44 +423,7 @@ void dram_t::issueCMD() //if mrq is being serviced by dram, gets popped after CL latency fulfilled class mem_fetch* dram_t::pop() { - class mem_fetch *data = NULL; - dram_req_t *mrq = rwq->pop(gpu_sim_cycle); - if (mrq) { -#ifdef DRAM_VIEWCMD - printf("\tDQ: BK%d Row:%03x Col:%03x", - mrq->bk, mrq->row, mrq->col + mrq->dqbytes); -#endif - mrq->dqbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; /*16 bytes*/ - if (mrq->dqbytes >= mrq->nbytes) { - if (m_config->gpgpu_memlatency_stat) { - unsigned dq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - mrq->timestamp; - m_stats->dq_lat_table[LOGB2(dq_latency)]++; - if (dq_latency > m_stats->max_dq_latency) - m_stats->max_dq_latency = dq_latency; - } - data = mrq->data; - delete mrq; - } - } -#ifdef DRAM_VIEWCMD - printf("\n"); -#endif - return data; -} - -void dram_t::returnq_push( class mem_fetch *mf, unsigned long long gpu_sim_cycle) -{ - returnq->push(mf,gpu_sim_cycle); -} - -class mem_fetch* dram_t::returnq_pop( unsigned long long gpu_sim_cycle) -{ - return returnq->pop(gpu_sim_cycle); -} - -class mem_fetch* dram_t::returnq_top() -{ - return returnq->top(); + return returnq->pop(); } void dram_t::print( FILE* simFile) const @@ -501,15 +483,6 @@ void dram_t::print_stat( FILE* simFile ) max_mrqs_temp = 0; } -void dram_t::queue_latency_log_dump( FILE *fp ) -{ - fprintf(fp,"(LOGB2)Latency DRAM[%d] ",id); - StatDisp(mrqq->get_lat_stat()); - fprintf(fp,"(LOGB2)Latency DRAM[%d] ",id); - StatDisp(rwq->get_lat_stat()); - dram_log(DUMPLOG); -} - void dram_t::visualizer_print( gzFile visualizer_file ) { // dram specific statistics |
