diff options
| author | Tor Aamodt <[email protected]> | 2010-10-02 19:53:47 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-10-02 19:53:47 -0800 |
| commit | 5c220c406491b72054a00d1dceab222ab796f06a (patch) | |
| tree | 507f791973f4b4b0d0c016a2b5385f0aba66224c | |
| parent | d3b9d526ecbf5e0bdaa91d21526cb56a2e98b534 (diff) | |
refactor: mem_fetch now a class
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7807]
| -rw-r--r-- | src/gpgpu-sim/dram.cc | 18 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.h | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 127 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 8 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 62 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.cc | 84 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.h | 113 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.cc | 57 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.h | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 34 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 41 | ||||
| -rw-r--r-- | src/intersim/interconnect_interface.cpp | 14 |
12 files changed, 281 insertions, 285 deletions
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index fe1b470..e798724 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -184,23 +184,25 @@ unsigned int dram_t::queue_limit() const dram_req_t::dram_req_t( class mem_fetch *mf ) { - bk = mf->tlx.bk; - row = mf->tlx.row; - col = mf->tlx.col; - nbytes = mf->nbytes_L1; txbytes = 0; dqbytes = 0; data = mf; + + const addrdec_t &tlx = mf->get_tlx_addr(); + + bk = tlx.bk; + row = tlx.row; + col = tlx.col; + nbytes = mf->get_data_size(); + timestamp = gpu_tot_sim_cycle + gpu_sim_cycle; - cache_hits_waiting = mf->cache_hits_waiting; - addr = mf->addr; + addr = mf->get_addr(); insertion_time = (unsigned) gpu_sim_cycle; - rw = data->m_write?WRITE:READ; + rw = data->get_is_write()?WRITE:READ; } void dram_t::push( class mem_fetch *data ) { - assert(data->tlx.bk<nbk); dram_req_t *mrq = new dram_req_t(data); mrqq->push(mrq,gpu_sim_cycle); diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index ee7f7a7..5428533 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -81,9 +81,10 @@ #define BANK_IDLE 'I' #define BANK_ACTIVE 'A' -struct dram_req_t -{ +class dram_req_t { +public: dram_req_t( class mem_fetch *data ); + unsigned int row; unsigned int col; unsigned int bk; @@ -96,7 +97,6 @@ struct dram_req_t unsigned long long int addr; unsigned int insertion_time; class mem_fetch * data; - int cache_hits_waiting; }; struct bank_t diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index dc76f53..23dc651 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1036,36 +1036,19 @@ unsigned char gpgpu_sim::check_icnt_has_buffer(unsigned long long int addr, int return icnt_has_buffer(tpc_id, bsize); } -unsigned gpgpu_sim::get_L2_linesize() const -{ - if (m_memory_partition_unit[0]->has_cache()) - return m_memory_partition_unit[0]->L2c_get_linesize(); - else - return 0; -} - int gpgpu_sim::issue_mf_from_fq(mem_fetch *mf) { - m_memory_stats->memlatstat_start(mf); - int destination; // where is the next level of memory? - destination = mf->tlx.chip; - int tpc_id = mf->sid / gpu_concentration; - - if (mf->mshr) mf->mshr->set_status(IN_ICNT2MEM); - if (!mf->m_write) { - mf->type = RD_REQ; - assert( mf->timestamp == (gpu_sim_cycle+gpu_tot_sim_cycle) ); - if( mf->mshr && mf->mshr->has_inst() ) - time_vector_update(mf->mshr->get_insts_uid(), MR_ICNT_PUSHED, gpu_sim_cycle+gpu_tot_sim_cycle, mf->type ); - icnt_push(tpc_id, mem2device(destination), (void*)mf, READ_PACKET_SIZE); + unsigned destination = mf->get_tlx_addr().chip; + unsigned tpc_id = mf->get_tpc(); + mf->set_status(IN_ICNT2MEM,MR_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle); + if (!mf->get_is_write()) { + mf->set_type(RD_REQ); + icnt_push(tpc_id, mem2device(destination), (void*)mf, mf->get_ctrl_size() ); } else { - mf->type = WT_REQ; - icnt_push(tpc_id, mem2device(destination), (void*)mf, mf->nbytes_L1); + mf->set_type(WT_REQ); + icnt_push(tpc_id, mem2device(destination), (void*)mf, mf->size()); gpgpu_n_sent_writes++; - assert( mf->timestamp == (gpu_sim_cycle+gpu_tot_sim_cycle) ); - time_vector_update(mf->request_uid, MR_ICNT_PUSHED, gpu_sim_cycle+gpu_tot_sim_cycle, mf->type ) ; } - return 0; } @@ -1073,19 +1056,18 @@ void shader_core_ctx::fill_shd_L1_with_new_line(mem_fetch * mf) { // When the data arrives, it flags all the appropriate MSHR // entries accordingly (by checking the address in each entry ) - if (mf->mshr->isinst()) { - m_L1I->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle); - m_warp[mf->mshr->get_warp_id()].clear_imiss_pending(); - delete mf->mshr; - mf->mshr=NULL; + if ( mf->isinst() ) { + m_L1I->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle); + m_warp[mf->get_wid()].clear_imiss_pending(); + delete mf->get_mshr(); } else { - m_mshr_unit->mshr_return_from_mem(mf->mshr); - if (mf->mshr->istexture()) - m_L1T->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle); - else if (mf->mshr->isconst()) - m_L1C->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle); + m_mshr_unit->mshr_return_from_mem(mf->get_mshr()); + if (mf->istexture()) + m_L1T->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle); + else if (mf->isconst()) + m_L1C->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle); else if (!m_config->gpgpu_no_dl1) - m_L1D->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L1D->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle); } freed_read_mfs++; delete mf; @@ -1094,7 +1076,7 @@ void shader_core_ctx::fill_shd_L1_with_new_line(mem_fetch * mf) void shader_core_ctx::store_ack( class mem_fetch *mf ) { if (!strcmp("GT200",m_config->pipeline_model) ) { - unsigned warp_id = mf->wid; + unsigned warp_id = mf->get_wid(); m_warp[warp_id].dec_store_req(); } } @@ -1104,15 +1086,14 @@ void gpgpu_sim::fq_pop(int tpc_id) mem_fetch *mf = (mem_fetch*) icnt_pop(tpc_id); if (!mf) return; - assert(mf->type == REPLY_DATA); - if( mf->mshr && mf->mshr->has_inst() ) - time_vector_update(mf->mshr->get_insts_uid() ,MR_2SH_FQ_POP,gpu_sim_cycle+gpu_tot_sim_cycle, mf->type ); - if (mf->m_write) { - m_sc[mf->sid]->store_ack(mf); + assert(mf->get_type() == REPLY_DATA); + mf->set_status(IN_ICNT2SHADER,MR_2SH_FQ_POP,gpu_sim_cycle+gpu_tot_sim_cycle); + if (mf->get_is_write()) { + m_sc[mf->get_sid()]->store_ack(mf); delete mf; } else { m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader); - m_sc[mf->sid]->fill_shd_L1_with_new_line(mf); + m_sc[mf->get_sid()]->fill_shd_L1_with_new_line(mf); } } @@ -1201,24 +1182,17 @@ void memory_partition_unit::push( mem_fetch* req, unsigned long long cycle ) if ( !m_rop.empty() && (cycle >= m_rop.front().ready_cycle) ) { mem_fetch* mf = m_rop.front().req; m_rop.pop(); - if (mf->type==RD_REQ) { - if ( mf->mshr && mf->mshr->has_inst() ) - time_vector_update(mf->mshr->get_insts_uid(),MR_DRAMQ,gpu_sim_cycle+gpu_tot_sim_cycle,mf->type ) ; - } else { - if ( mf->mshr && !mf->mshr->isinst() ) - time_vector_update(mf->request_uid ,MR_DRAMQ,gpu_sim_cycle+gpu_tot_sim_cycle,mf->type ) ; - } m_stats->memlatstat_icnt2mem_pop(mf); if (m_config->gpgpu_cache_dl2_opt) { - if (m_config->gpgpu_l2_readoverwrite && mf->m_write) + if (m_config->gpgpu_l2_readoverwrite && mf->get_is_write()) m_icnt2cache_write_queue->push(mf,gpu_sim_cycle); else m_icnt2cache_queue->push(mf,gpu_sim_cycle); m_accessLocality->access(mf); - if (mf->mshr) mf->mshr->set_status(IN_CBTOL2QUEUE); + mf->set_status(IN_CBTOL2QUEUE,MR_DRAMQ,gpu_sim_cycle+gpu_tot_sim_cycle); } else { m_dram->push(mf); - if (mf->mshr) mf->mshr->set_status(IN_DRAM_REQ_QUEUE); + mf->set_status(IN_DRAM_REQ_QUEUE,MR_DRAMQ,gpu_sim_cycle+gpu_tot_sim_cycle); } } } @@ -1228,17 +1202,13 @@ mem_fetch* memory_partition_unit::pop() mem_fetch* mf; if (m_config->gpgpu_cache_dl2_opt) { mf = L2tocbqueue->pop(gpu_sim_cycle); - if (mf && mf->mshr && mf->mshr->isatomic() ) { - dram_callback_t &cb = mf->mshr->get_atomic_callback(); - cb.function(cb.instruction, cb.thread); - } + if ( mf->isatomic() ) + mf->do_atomic(); } else { mf = m_dram->returnq_pop(gpu_sim_cycle); - if (mf) mf->type = REPLY_DATA; - if (mf && mf->mshr && mf->mshr->isatomic() ) { - dram_callback_t &cb = mf->mshr->get_atomic_callback(); - cb.function(cb.instruction, cb.thread); - } + if (mf) mf->set_type( REPLY_DATA ); + if (mf->isatomic() ) + mf->do_atomic(); } m_request_tracker.erase(mf); return mf; @@ -1250,7 +1220,7 @@ mem_fetch* memory_partition_unit::top() return L2tocbqueue->top(); } else { mem_fetch* mf = m_dram->returnq_top(); - if (mf) mf->type = REPLY_DATA; + if (mf) mf->set_type( REPLY_DATA ); return mf; } } @@ -1262,12 +1232,11 @@ void memory_partition_unit::issueCMD() if ( !(dramtoL2queue->full() || dramtoL2writequeue->full()) ) { mem_fetch* mf = m_dram->pop(); if (mf) { - if (m_config->gpgpu_l2_readoverwrite && mf->m_write) + if (m_config->gpgpu_l2_readoverwrite && mf->get_is_write() ) dramtoL2writequeue->push(mf,gpu_sim_cycle); else dramtoL2queue->push(mf,gpu_sim_cycle); - if (mf->mshr) - mf->mshr->set_status(IN_DRAMTOL2QUEUE); + mf->set_status(IN_DRAMTOL2QUEUE,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); } } } else { @@ -1276,8 +1245,7 @@ void memory_partition_unit::issueCMD() mem_fetch* mf = m_dram->pop(); if (mf) { m_dram->returnq_push(mf,gpu_sim_cycle); - if (mf->mshr) - mf->mshr->set_status(IN_DRAMRETURN_Q); + mf->set_status(IN_DRAMRETURN_Q,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); } } m_dram->issueCMD(); @@ -1330,27 +1298,21 @@ void gpgpu_sim::gpu_sim_loop() for (int i=0;i<gpu_n_tpc;i++) fq_pop(i); } - if (clock_mask & ICNT) { // pop from memory controller to interconnect for (unsigned i=0;i<m_n_mem;i++) { mem_fetch* mf = m_memory_partition_unit[i]->top(); if (mf) { - assert( mf->type != RD_REQ && mf->type != WT_REQ ); - unsigned response_size = mf->m_write?mf->nbytes_L1:WRITE_PACKET_SIZE; + mf->set_status(IN_ICNT2SHADER,MR_2SH_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle); + unsigned response_size = mf->get_is_write()?mf->get_ctrl_size():mf->size(); if ( icnt_has_buffer( mem2device(i), response_size ) ) { - if (!mf->m_write) { - if (mf->mshr) mf->mshr->set_status(IN_ICNT2SHADER); - m_memory_stats->memlatstat_icnt2sh_push(mf); - if ( mf->mshr && mf->mshr->has_inst() ) - time_vector_update(mf->mshr->get_insts_uid(),MR_2SH_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle,RD_REQ); - } else { - time_vector_update(mf->request_uid ,MR_2SH_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle,WT_REQ ) ; + if (!mf->get_is_write()) + mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle); + else { freed_L1write_mfs++; gpgpu_n_processed_writes++; } - int return_dev = mf->sid / gpu_concentration; - icnt_push( mem2device(i), return_dev, mf, response_size ); + icnt_push( mem2device(i), mf->get_tpc(), mf, response_size ); m_memory_partition_unit[i]->pop(); } else { gpu_stall_icnt2sh++; @@ -1360,9 +1322,8 @@ void gpgpu_sim::gpu_sim_loop() } if (clock_mask & DRAM) { - for (unsigned i=0;i<m_n_mem;i++) { + for (unsigned i=0;i<m_n_mem;i++) m_memory_partition_unit[i]->issueCMD(); // Issue the dram command (scheduler + delay model) - } } // L2 operations follow L2 clock domain @@ -1374,7 +1335,7 @@ void gpgpu_sim::gpu_sim_loop() if (clock_mask & ICNT) { for (unsigned i=0;i<m_n_mem;i++) { if ( m_memory_partition_unit[i]->full() ) { - gpu_stall_dramfull++; + gpu_stall_dramfull++; continue; } // move memory request from interconnect into memory partition (if memory controller not backed up) diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 5bb9875..2aad778 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -270,8 +270,6 @@ public: unsigned run_gpu_sim(); - unsigned get_L2_linesize() const; - unsigned char fq_has_buffer(unsigned long long int addr, int bsize, bool write, int sid ); void decrement_atomic_count( unsigned sid, unsigned wid ); void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ); @@ -286,11 +284,11 @@ public: unsigned num_shader() const { return m_n_shader; } unsigned threads_per_core() const; - void mem_instruction_stats( class inst_t* warp); + void mem_instruction_stats( class inst_t* warp); int issue_mf_from_fq(class mem_fetch *mf); - void gpu_print_stat() const; - void dump_pipeline( int mask, int s, int m ) const; + void gpu_print_stat() const; + void dump_pipeline( int mask, int s, int m ) const; private: // clocks diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 0bf8af6..e315b45 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -93,17 +93,17 @@ extern unsigned freed_L2write_mfs; address_type L2c_mshr::cache_tag(const mem_fetch *mf) const { - return (mf->addr & ~(m_linesize - 1)); + return (mf->get_addr() & ~(m_linesize - 1)); } address_type L2c_miss_tracker::cache_tag(const mem_fetch *mf) const { - return (mf->addr & ~(m_linesize - 1)); + return (mf->get_addr() & ~(m_linesize - 1)); } address_type L2c_access_locality::cache_tag(const mem_fetch *mf) const { - return (mf->addr & ~(m_linesize - 1)); + return (mf->get_addr() & ~(m_linesize - 1)); } void gpgpu_sim::L2c_options(option_parser_t opp) @@ -148,8 +148,8 @@ void L2c_mshr::miss_serviced(const mem_fetch *mf) assert(m_active_mshr_chain.list == NULL); address_type cacheTag = cache_tag(mf); L2missGroup::iterator missGroup = m_L2missgroup.find(cacheTag); - if (missGroup == m_L2missgroup.end() || mf->type == L2_WTBK_DATA) { - assert(mf->type == L2_WTBK_DATA); // only this returning mem req can be missed by the MSHR + if (missGroup == m_L2missgroup.end() || mf->get_type() == L2_WTBK_DATA) { + assert(mf->get_type() == L2_WTBK_DATA); // only this returning mem req can be missed by the MSHR return; } assert(missGroup->first == cacheTag); @@ -191,9 +191,8 @@ void L2c_mshr::print(FILE *fout) for (missGroup = m_L2missgroup.begin(); missGroup != m_L2missgroup.end(); ++missGroup) { fprintf(fout, "%#08x: ", missGroup->first); mem_fetch_list &mf_list = missGroup->second; - for (mem_fetch_list::iterator imf = mf_list.begin(); imf != mf_list.end(); ++imf) { - fprintf(fout, "%p:%d ", *imf, (*imf)->request_uid); - } + for (mem_fetch_list::iterator imf = mf_list.begin(); imf != mf_list.end(); ++imf) + (*imf)->print(fout); fprintf(fout, "\n"); } } @@ -396,19 +395,18 @@ void memory_partition_unit::L2c_service_mem_req() mf = m_icnt2cache_write_queue->pop(gpu_sim_cycle); if( !mf ) return; - switch (mf->type) { + switch (mf->get_type()) { case RD_REQ: case WT_REQ: { address_type rep_block; - enum cache_request_status status = m_L2cache->access( mf->addr, 4, mf->m_write, gpu_sim_cycle, &rep_block); + enum cache_request_status status = m_L2cache->access( mf->get_addr(), 4, mf->get_is_write(), gpu_sim_cycle, &rep_block); if( (status==HIT) || m_config->l2_ideal ) { - mf->type = REPLY_DATA; + mf->set_type( REPLY_DATA ); L2tocbqueue->push(mf,gpu_sim_cycle); - if (!mf->m_write) { + if (!mf->get_is_write()) { m_stats->L2_read_hit++; - m_stats->memlatstat_icnt2sh_push(mf); - if (mf->mshr) - mf->mshr->set_status(IN_L2TOCBQUEUE_HIT); + mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_L2TOCBQUEUE_HIT,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); } else { m_stats->L2_write_hit++; freed_L1write_mfs++; @@ -420,15 +418,9 @@ void memory_partition_unit::L2c_service_mem_req() // this miss just need to access the cache later when this request is serviced bool mshr_hit = m_mshr->new_miss(mf); if (not mshr_hit) { - if (mf->m_write) { - // if request is writeback from L1 and misses, - // then redirect mf writes to dram (no write allocate) - mf->nbytes_L2 = mf->nbytes_L1 - READ_PACKET_SIZE; - } L2todramqueue->push(mf,gpu_sim_cycle); } - if (mf->mshr) - mf->mshr->set_status(IN_L2TODRAMQUEUE); + mf->set_status(IN_L2TODRAMQUEUE,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); } } break; @@ -444,14 +436,13 @@ void memory_partition_unit::L2c_push_miss_to_dram() mem_fetch* mf = L2todram_wbqueue->pop(gpu_sim_cycle); //prioritize writeback if (!mf) mf = L2todramqueue->pop(gpu_sim_cycle); if (mf) { - if (mf->m_write) { + if (mf->get_is_write()) m_stats->L2_write_miss++; - } else { + else m_stats->L2_read_miss++; - } m_missTracker->new_miss(mf); m_dram->push(mf); - if (mf->mshr) mf->mshr->set_status(IN_DRAM_REQ_QUEUE); + mf->set_status(IN_DRAM_REQ_QUEUE, MR_DRAMQ, gpu_sim_cycle+gpu_tot_sim_cycle); } } @@ -479,19 +470,18 @@ void memory_partition_unit::process_dram_output() } mem_fetch* mf = L2dramout; if (mf) { - if (!mf->m_write) { //service L2 read miss + if (!mf->get_is_write()) { //service L2 read miss // it is a pre-fill dramout mf if (wb_addr == (unsigned long long int)-1) { if ( L2tocbqueue->full() ) { assert (L2dramout || wb_addr == (unsigned long long int)-1); return; } - if (mf->mshr) - mf->mshr->set_status(IN_L2TOCBQUEUE_MISS); + mf->set_status(IN_L2TOCBQUEUE_MISS,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); //only transfer across icnt once the whole line has been received by L2 cache - mf->type = REPLY_DATA; + mf->set_type(REPLY_DATA); L2tocbqueue->push(mf,gpu_sim_cycle); - wb_addr = m_L2cache->shd_cache_fill(mf->addr, gpu_sim_cycle); + wb_addr = m_L2cache->shd_cache_fill(mf->get_addr(), gpu_sim_cycle); } // only perform a write on cache eviction (write-back policy) // it is the 1st or nth time trial to writeback @@ -527,14 +517,16 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi if ( L2todram_wbqueue->full() ) return false; mem_fetch *mf = new mem_fetch(addr, - bsize+READ_PACKET_SIZE/*l1*/, - bsize/*l2*/, - 0/*sid*/,0/*tpc*/,0/*wid*/,0/*cache_hits_waiting*/,NULL,true, + bsize, + READ_PACKET_SIZE, + (unsigned)-1/*sid*/, + (unsigned)-1/*tpc*/, + (unsigned)-1/*wid*/, + NULL,true, partial_write_mask_t(), L2_WRBK_ACC, L2_WTBK_DATA, -1/*pc*/); - m_stats->memlatstat_start(mf); made_write_mfs++; L2todram_wbqueue->push(mf,gpu_sim_cycle); gpgpu_n_sent_writes++; diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index 58ed2cd..a3a423a 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -65,48 +65,84 @@ #include "mem_fetch.h" #include "mem_latency_stat.h" +#include "shader.h" +#include "visualizer.h" +#include "gpu-sim.h" unsigned mem_fetch::sm_next_mf_request_uid=1; -mem_fetch::mem_fetch( unsigned long long int addr, - int l1bsize, - int l2bsize, - int sid, - unsigned tpc, - int wid, - int cache_hits_waiting, - class mshr_entry * mshr, - bool write, - partial_write_mask_t partial_write_mask, - enum mem_access_type mem_acc, - enum mf_type type, - address_type pc ) +mem_fetch::mem_fetch( new_addr_type addr, + unsigned data_size, + unsigned ctrl_size, + unsigned sid, + unsigned tpc, + unsigned wid, + class mshr_entry * mshr, + bool write, + partial_write_mask_t partial_write_mask, + enum mem_access_type mem_acc, + enum mf_type type, + address_type pc ) { class mem_fetch *mf = this; mf->request_uid = sm_next_mf_request_uid++; + mf->addr = addr; - mf->nbytes_L1 = l1bsize; - mf->nbytes_L2 = l2bsize; + mf->nbytes_L1 = data_size; + mf->ctrl_size = ctrl_size; mf->sid = sid; mf->wid = wid; - mf->cache_hits_waiting = cache_hits_waiting; - mf->txbytes_L1 = 0; - mf->rxbytes_L1 = 0; + mf->tpc = tpc; mf->mshr = mshr; mf->m_write = write; addrdec_tlx(addr,&mf->tlx); - mf->bank = mf->tlx.bk; - mf->chip = mf->tlx.chip; - mf->txbytes_L2 = 0; - mf->rxbytes_L2 = 0; - mf->write_mask = partial_write_mask; mf->mem_acc = mem_acc; mf->type = type; mf->pc = pc; + mf->timestamp = gpu_sim_cycle + gpu_tot_sim_cycle; + mf->timestamp2 = 0; } void mem_fetch::print( FILE *fp ) const { fprintf(fp," mf: uid=%6u, addr=0x%08llx, sid=%u, wid=%u, pc=0x%04x, %s, bank=%u\n", - request_uid, addr, sid, wid, pc, (m_write?"write":"read "), bank); + request_uid, addr, sid, wid, pc, (m_write?"write":"read "), tlx.bk); +} + +void mem_fetch::set_status( enum mshr_status status, enum mem_req_stat stat, unsigned long long cycle ) +{ + if ( mshr ) { + mshr->set_status(status); + if( mshr->has_inst() ) + time_vector_update(mshr->get_insts_uid(),stat,cycle,type); + else + time_vector_update(request_uid,stat,cycle,type); + } +} + +bool mem_fetch::isatomic() const +{ + if( !mshr ) return false; + return mshr->isatomic(); +} + +void mem_fetch::do_atomic() +{ + dram_callback_t &cb = mshr->get_atomic_callback(); + cb.function(cb.instruction, cb.thread); +} + +bool mem_fetch::isinst() const +{ + return (mshr==NULL)?false:mshr->isinst(); +} + +bool mem_fetch::istexture() const +{ + return (mshr==NULL)?false:mshr->istexture(); +} + +bool mem_fetch::isconst() const +{ + return (mshr==NULL)?false:mshr->isconst(); } diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index 9e9ff9a..0aab2cb 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -91,18 +91,53 @@ enum mem_access_type { NUM_MEM_ACCESS_TYPE = 8 }; +enum mshr_status { + INITIALIZED = 0, + INVALID, + IN_ICNT2MEM, + IN_CBTOL2QUEUE, + IN_L2TODRAMQUEUE, + IN_DRAM_REQ_QUEUE, + IN_DRAMRETURN_Q, + IN_DRAMTOL2QUEUE, + IN_L2TOCBQUEUE_HIT, + IN_L2TOCBQUEUE_MISS, + IN_ICNT2SHADER, + FETCHED, + NUM_MSHR_STATUS +}; + +//used to stages that time_vector will keep track of their timing +enum mem_req_stat { + MR_UNUSED, + MR_FQPUSHED, + MR_ICNT_PUSHED, + MR_ICNT_INJECTED, + MR_ICNT_AT_DEST, + MR_DRAMQ, //icnt_pop at dram side and mem_ctrl_push + MR_DRAM_PROCESSING_START, + MR_DRAM_PROCESSING_END, + MR_DRAM_OUTQ, + MR_2SH_ICNT_PUSHED, // icnt_push and mem_ctl_pop //STORES END HERE! + MR_2SH_ICNT_INJECTED, + MR_2SH_ICNT_AT_DEST, + MR_2SH_FQ_POP, //icnt_pop called inside fq_pop + MR_RETURN_Q, + MR_WRITEBACK, //done + NUM_MEM_REQ_STAT +}; + const unsigned partial_write_mask_bits = 128; //must be at least size of largest memory access. typedef std::bitset<partial_write_mask_bits> partial_write_mask_t; class mem_fetch { public: - mem_fetch( unsigned long long int addr, - int l1bsize, - int l2bsize, - int sid, - unsigned tpc, - int wid, - int cache_hits_waiting, + mem_fetch( new_addr_type addr, + unsigned data_size, + unsigned ctrl_size, + unsigned sid, + unsigned tpc, + unsigned wid, class mshr_entry * mshr, bool write, partial_write_mask_t partial_write_mask, @@ -110,32 +145,60 @@ public: enum mf_type type, address_type pc ); + void set_status( enum mshr_status status, enum mem_req_stat stat, unsigned long long cycle ); + void set_type( enum mf_type t ) { type=t; } + void do_atomic(); + void print( FILE *fp ) const; -public: + const addrdec_t &get_tlx_addr() const { return tlx; } + unsigned get_data_size() const { return nbytes_L1; } + unsigned get_ctrl_size() const { return ctrl_size; } + unsigned size() const { return nbytes_L1+ctrl_size; } + new_addr_type get_addr() const { return addr; } + class mshr_entry *get_mshr() { return mshr; } + bool get_is_write() const { return m_write; } + unsigned get_request_uid() const { return request_uid; } + unsigned get_sid() const { return sid; } + unsigned get_tpc() const { return tpc; } + unsigned get_wid() const { return wid; } + bool isinst() const; + bool istexture() const; + bool isconst() const; + enum mf_type get_type() const { return type; } + bool isatomic() const; + void set_return_timestamp( unsigned t ) { timestamp2=t; } + void set_icnt_receive_time( unsigned t ) { icnt_receive_time=t; } + unsigned get_timestamp() const { return timestamp; } + unsigned get_return_timestamp() const { return timestamp2; } + unsigned get_icnt_receive_time() const { return icnt_receive_time; } + enum mem_access_type get_mem_acc() const { return mem_acc; } + address_type get_pc() const { return pc; } + +private: + // request origination unsigned request_uid; - unsigned long long int addr; - int nbytes_L1; - int txbytes_L1; - int rxbytes_L1; - int nbytes_L2; - int txbytes_L2; - int rxbytes_L2; - int sid; //shader core id - int wid; //warp id - int cache_hits_waiting; - class mshr_entry* mshr; address_type pc; + unsigned sid; + unsigned tpc; + unsigned wid; + class mshr_entry* mshr; + + // request type, address, size, mask bool m_write; enum mem_access_type mem_acc; - unsigned int timestamp; //set to gpu_sim_cycle at struct creation - unsigned int timestamp2; //set to gpu_sim_cycle when pushed onto icnt to shader; only used for reads - unsigned int icnt_receive_time; //set to gpu_sim_cycle + interconnect_latency when fixed icnt latency mode is enabled - unsigned char bank; - unsigned char chip; - addrdec_t tlx; enum mf_type type; + new_addr_type addr; + addrdec_t tlx; partial_write_mask_t write_mask; + unsigned nbytes_L1; + unsigned ctrl_size; + + // statistics + unsigned timestamp; // set to gpu_sim_cycle+gpu_tot_sim_cycle at struct creation + unsigned timestamp2; // set to gpu_sim_cycle+gpu_tot_sim_cycle when pushed onto icnt to shader; only used for reads + unsigned icnt_receive_time; // set to gpu_sim_cycle + interconnect_latency when fixed icnt latency mode is enabled + static unsigned sm_next_mf_request_uid; }; diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index cd1a650..28e9036 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -159,49 +159,35 @@ memory_stats_t::memory_stats_t( unsigned n_mem, unsigned n_shader, struct shader L2_L2todramlength = (unsigned int*) calloc(n_mem, sizeof(unsigned int)); } -void memory_stats_t::memlatstat_start(mem_fetch *mf) -{ - mf->timestamp = gpu_sim_cycle + gpu_tot_sim_cycle; - mf->timestamp2 = 0; -} - // recorder the total latency unsigned memory_stats_t::memlatstat_done(mem_fetch *mf, unsigned n_warp_per_shader ) { unsigned mf_latency; - unsigned wid = mf->sid*n_warp_per_shader + mf->wid; + unsigned wid = mf->get_sid()*n_warp_per_shader + mf->get_wid(); assert(wid<max_warps); - mf_latency = (gpu_sim_cycle+gpu_tot_sim_cycle) - mf->timestamp; + mf_latency = (gpu_sim_cycle+gpu_tot_sim_cycle) - mf->get_timestamp(); mf_num_lat_pw++; mf_num_lat_pw_perwarp[wid]++; mf_tot_lat_pw_perwarp[wid] += mf_latency; mf_tot_lat_pw += mf_latency; - if( mf->mshr && mf->mshr->has_inst() ) - check_time_vector_update(mf->mshr->get_insts_uid(),MR_2SH_FQ_POP,mf_latency,mf->type); + if( mf->get_mshr() && mf->get_mshr()->has_inst() ) + check_time_vector_update(mf->get_mshr()->get_insts_uid(),MR_2SH_FQ_POP,mf_latency,mf->get_type()); mf_lat_table[LOGB2(mf_latency)]++; - shader_mem_lat_log(mf->sid, mf_latency); - mf_total_lat_table[mf->chip][mf->bank] += mf_latency; + shader_mem_lat_log(mf->get_sid(), mf_latency); + mf_total_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk] += mf_latency; if (mf_latency > max_mf_latency) max_mf_latency = mf_latency; return mf_latency; } -void memory_stats_t::memlatstat_icnt2sh_push(mem_fetch *mf) -{ - mf->timestamp2 = gpu_sim_cycle+gpu_tot_sim_cycle; -} - void memory_stats_t::memlatstat_read_done(mem_fetch *mf, unsigned n_warp_per_shader) { if (m_memory_config->gpgpu_memlatency_stat) { unsigned mf_latency = memlatstat_done(mf,n_warp_per_shader); - - if (mf_latency > mf_max_lat_table[mf->chip][mf->bank]) { - mf_max_lat_table[mf->chip][mf->bank] = mf_latency; - } - + if (mf_latency > mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk]) + 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->timestamp2; + icnt2sh_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_return_timestamp(); icnt2sh_lat_table[LOGB2(icnt2sh_latency)]++; if (icnt2sh_latency > max_icnt2sh_latency) max_icnt2sh_latency = icnt2sh_latency; @@ -210,24 +196,23 @@ void memory_stats_t::memlatstat_read_done(mem_fetch *mf, unsigned n_warp_per_sha void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) { - unsigned dram_id = mf->chip; - unsigned bank = mf->bank; + unsigned dram_id = mf->get_tlx_addr().chip; + unsigned bank = mf->get_tlx_addr().bk; if (m_memory_config->gpgpu_memlatency_stat) { - if (mf->m_write) { - if ( (unsigned) mf->sid < m_n_shader ) { //do not count L2_writebacks here - bankwrites[mf->sid][dram_id][bank]++; - shader_mem_acc_log( mf->sid, dram_id, bank, 'w'); + if (mf->get_is_write()) { + if ( mf->get_sid() < m_n_shader ) { //do not count L2_writebacks here + bankwrites[mf->get_sid()][dram_id][bank]++; + shader_mem_acc_log( mf->get_sid(), dram_id, bank, 'w'); } totalbankwrites[dram_id][bank]++; } else { - bankreads[mf->sid][dram_id][bank]++; - shader_mem_acc_log( mf->sid, dram_id, bank, 'r'); + bankreads[mf->get_sid()][dram_id][bank]++; + shader_mem_acc_log( mf->get_sid(), dram_id, bank, 'r'); totalbankreads[dram_id][bank]++; } - if (mf->pc != (unsigned) -1) { - ptx_file_line_stats_add_dram_traffic(mf->pc, 1); - } - mem_access_type_stats[mf->mem_acc][dram_id][bank]++; + if (mf->get_pc() != (unsigned)-1) + ptx_file_line_stats_add_dram_traffic(mf->get_pc(),1); + mem_access_type_stats[mf->get_mem_acc()][dram_id][bank]++; } } @@ -235,7 +220,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->timestamp; + icnt2mem_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_timestamp(); icnt2mem_lat_table[LOGB2(icnt2mem_latency)]++; if (icnt2mem_latency > max_icnt2mem_latency) max_icnt2mem_latency = icnt2mem_latency; diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h index c228c6e..c2a09b7 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -77,9 +77,7 @@ public: struct shader_core_config *shader_config, struct memory_config *mem_config ); - void memlatstat_start( class mem_fetch *mf); unsigned memlatstat_done( class mem_fetch *mf, unsigned n_warp_per_shader ); - void memlatstat_icnt2sh_push( class mem_fetch *mf); void memlatstat_read_done( class mem_fetch *mf, unsigned n_warp_per_shader); void memlatstat_dram_access( class mem_fetch *mf ); void memlatstat_icnt2mem_pop( class mem_fetch *mf); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 75aec7b..c470c94 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -273,25 +273,22 @@ unsigned char shader_core_ctx::fq_push(unsigned long long int addr, partial_write_mask_t partial_write_mask, int wid, mshr_entry* mshr, - int cache_hits_waiting, enum mem_access_type mem_acc, address_type pc) { assert(write || (partial_write_mask == NO_PARTIAL_WRITE)); - int nbytes_L2 = m_gpu->get_L2_linesize(); mem_fetch *mf = new mem_fetch(addr, - bsize, - nbytes_L2, - m_sid, - m_tpc, - wid, - cache_hits_waiting, - mshr, - write, - partial_write_mask, - mem_acc, - write?WT_REQ:RD_REQ, - pc); + bsize, + (write?WRITE_PACKET_SIZE:READ_PACKET_SIZE), + m_sid, + m_tpc, + wid, + mshr, + write, + partial_write_mask, + mem_acc, + (write?WT_REQ:RD_REQ), + pc); if (mshr) mshr->set_mf(mf); // stats @@ -1173,7 +1170,7 @@ void shader_core_ctx::fetch_new() fq_push( pc, req_size, false, NO_PARTIAL_WRITE, warp_id, - mshr, 0, + mshr, INST_ACC_R, pc ); m_warp[warp_id].set_imiss_pending(mshr); m_warp[warp_id].set_last_fetch(gpu_sim_cycle); @@ -1963,7 +1960,7 @@ mem_stage_stall_type shader_core_ctx::send_mem_request(mem_access_t &access) m_stats->gpu_stall_sh2icnt++; return WB_ICNT_RC_FAIL; } - fq_push( access.wb_addr, req_size, true, NO_PARTIAL_WRITE, -1, NULL, 0, + fq_push( access.wb_addr, req_size, true, NO_PARTIAL_WRITE, -1, NULL, is_local(access.space)?LOCAL_ACC_W:GLOBAL_ACC_W, //space of cache line is same as new request -1); m_stats->L1_writeback++; @@ -2005,7 +2002,6 @@ mem_stage_stall_type shader_core_ctx::send_mem_request(mem_access_t &access) return ICNT_RC_FAIL; } //send over interconnect - unsigned cache_hits_waiting = 0; partial_write_mask_t write_mask = NO_PARTIAL_WRITE; unsigned warp_id = req_head->hw_thread_id/m_config->warp_size; if (access.iswrite) { @@ -2021,7 +2017,7 @@ mem_stage_stall_type shader_core_ctx::send_mem_request(mem_access_t &access) } fq_push( access.addr, request_size, access.iswrite, write_mask, warp_id , access.reserved_mshr, - cache_hits_waiting, access_type, req_head->pc); + access_type, req_head->pc); } // book keeping for mshr : this request is done (sent/accounted for) @@ -3364,7 +3360,7 @@ void mshr_entry::print(FILE *fp, unsigned mask) const (m_merged_requests != NULL || m_merged_on_other_reqest), MSHR_Status_str[m_status]); if ( m_mf ) - ptx_print_insn( m_mf->pc, fp ); + ptx_print_insn( m_mf->get_pc(), fp ); fprintf(fp,"\n"); if ( mask & 0x200 ) { for (unsigned i = 0; i < m_insts.size(); i++) { diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index fe6192a..e621aad 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -283,9 +283,12 @@ private: unsigned m_inst_in_pipeline; }; + + inline unsigned hw_tid_from_wid(unsigned wid, unsigned warp_size, unsigned i){return wid * warp_size + i;}; inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size){return tid/warp_size;}; + // bounded stack that implements pdom reconvergence (see MICRO'07 paper) class pdom_warp_ctx_t { public: @@ -315,43 +318,6 @@ private: }; -enum mshr_status { - INITIALIZED = 0, - INVALID, - IN_ICNT2MEM, - IN_CBTOL2QUEUE, - IN_L2TODRAMQUEUE, - IN_DRAM_REQ_QUEUE, - IN_DRAMRETURN_Q, - IN_DRAMTOL2QUEUE, - IN_L2TOCBQUEUE_HIT, - IN_L2TOCBQUEUE_MISS, - IN_ICNT2SHADER, - FETCHED, - NUM_MSHR_STATUS -}; - -//used to stages that time_vector will keep track of their timing -enum mem_req_stat { - MR_UNUSED, - MR_FQPUSHED, - MR_ICNT_PUSHED, - MR_ICNT_INJECTED, - MR_ICNT_AT_DEST, - MR_DRAMQ, //icnt_pop at dram side and mem_ctrl_push - MR_DRAM_PROCESSING_START, - MR_DRAM_PROCESSING_END, - MR_DRAM_OUTQ, - MR_2SH_ICNT_PUSHED, // icnt_push and mem_ctl_pop //STORES END HERE! - MR_2SH_ICNT_INJECTED, - MR_2SH_ICNT_AT_DEST, - MR_2SH_FQ_POP, //icnt_pop called inside fq_pop - MR_RETURN_Q, - MR_WRITEBACK, //done - NUM_MEM_REQ_STAT -}; -#include <vector> - class mshr_entry { public: mshr_entry() @@ -1183,7 +1149,6 @@ private: unsigned char write, partial_write_mask_t partial_write_mask, int wid, mshr_entry* mshr, - int cache_hits_waiting, enum mem_access_type mem_acc, address_type pc ); diff --git a/src/intersim/interconnect_interface.cpp b/src/intersim/interconnect_interface.cpp index b94e065..56b2d18 100644 --- a/src/intersim/interconnect_interface.cpp +++ b/src/intersim/interconnect_interface.cpp @@ -82,7 +82,7 @@ class mycomparison { public: bool operator() (const void* lhs, const void* rhs) const { - return( ((mem_fetch *)lhs)->icnt_receive_time > ((mem_fetch *) rhs)->icnt_receive_time); + return( ((mem_fetch *)lhs)->get_icnt_receive_time() > ((mem_fetch *) rhs)->get_icnt_receive_time()); } }; @@ -314,7 +314,7 @@ void interconnect_push ( unsigned int input_node, unsigned int output_node, #endif if (fixed_lat_icnt) { - ((mem_fetch *) data)->icnt_receive_time = gpu_sim_cycle + fixed_latency(input,output); + ((mem_fetch *) data)->set_icnt_receive_time( gpu_sim_cycle + fixed_latency(input,output) ); out_buf_fixedlat_buf[output].push(data); //deliver the whole packet to destination in zero cycles if (out_buf_fixedlat_buf[output].size() > max_fixedlat_buf_size[output]) { max_fixedlat_buf_size[output]= out_buf_fixedlat_buf[output].size(); @@ -348,10 +348,10 @@ void* interconnect_pop(unsigned int output_node) void* data = NULL; if (fixed_lat_icnt) { if (!out_buf_fixedlat_buf[output].empty()) { - if (((mem_fetch *)out_buf_fixedlat_buf[output].top())->icnt_receive_time <= gpu_sim_cycle) { + if (((mem_fetch *)out_buf_fixedlat_buf[output].top())->get_icnt_receive_time() <= gpu_sim_cycle) { data = out_buf_fixedlat_buf[output].top(); out_buf_fixedlat_buf[output].pop(); - assert (((mem_fetch *)data)->icnt_receive_time); + assert (((mem_fetch *)data)->get_icnt_receive_time()); } } } else { @@ -555,10 +555,10 @@ void time_vector_update(unsigned int uid, int slot , long int cycle, int type); void time_vector_update_icnt_injected(void* data, int input) { mem_fetch* mf = (mem_fetch*) data; - if( mf->mshr && !mf->mshr->isinst() ) { - unsigned uid=mf->m_write? mf->request_uid : mf->mshr->get_insts_uid(); + if( mf->get_mshr() && !mf->get_mshr()->isinst() ) { + unsigned uid=mf->get_is_write()? mf->get_request_uid() : mf->get_mshr()->get_insts_uid(); long int cycle = gpu_sim_cycle + gpu_tot_sim_cycle; - int req_type = mf->m_write? WT_REQ : RD_REQ; + int req_type = mf->get_is_write()? WT_REQ : RD_REQ; if (is_mem(input)) { time_vector_update( uid, MR_2SH_ICNT_INJECTED, cycle, req_type ); } else { |
