diff options
| author | tgrogers <[email protected]> | 2015-02-20 13:27:06 -0800 |
|---|---|---|
| committer | tgrogers <[email protected]> | 2015-02-20 13:27:06 -0800 |
| commit | d46bf67b50b265dd3afae7c9a6a13c4cbdd6176f (patch) | |
| tree | aef56cfce1cc6f595040cf51a3e39f324a41e512 /src/gpgpu-sim/shader.cc | |
| parent | 7cd0edfe0cb654280c30afef89a563867d9e67ed (diff) | |
| parent | 1e925effd20bf6fb78b19a4cdb96b17691a29b29 (diff) | |
Merge pull request #7 from andrewboktor/fix_icache
Fixing icache bug where for each miss we also count a hit.
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 156 |
1 files changed, 81 insertions, 75 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index b761dac..3c105ab 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -595,78 +595,84 @@ void shader_core_ctx::decode() void shader_core_ctx::fetch() { + if( !m_inst_fetch_buffer.m_valid ) { - // find an active warp with space in instruction buffer that is not already waiting on a cache miss - // and get next 1-2 instructions from i-cache... - for( unsigned i=0; i < m_config->max_warps_per_shader; i++ ) { - unsigned warp_id = (m_last_warp_fetched+1+i) % m_config->max_warps_per_shader; + if( m_L1I->access_ready() ) { + mem_fetch *mf = m_L1I->next_access(); + m_warp[mf->get_wid()].clear_imiss_pending(); + m_inst_fetch_buffer = ifetch_buffer_t(m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); + assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting. + m_inst_fetch_buffer.m_valid = true; + m_warp[mf->get_wid()].set_last_fetch(gpu_sim_cycle); + delete mf; + } + else { + // find an active warp with space in instruction buffer that is not already waiting on a cache miss + // and get next 1-2 instructions from i-cache... + for( unsigned i=0; i < m_config->max_warps_per_shader; i++ ) { + unsigned warp_id = (m_last_warp_fetched+1+i) % m_config->max_warps_per_shader; - // this code checks if this warp has finished executing and can be reclaimed - if( m_warp[warp_id].hardware_done() && !m_scoreboard->pendingWrites(warp_id) && !m_warp[warp_id].done_exit() ) { - bool did_exit=false; - for( unsigned t=0; t<m_config->warp_size;t++) { - unsigned tid=warp_id*m_config->warp_size+t; - if( m_threadState[tid].m_active == true ) { - m_threadState[tid].m_active = false; - unsigned cta_id = m_warp[warp_id].get_cta_id(); - register_cta_thread_exit(cta_id); - m_not_completed -= 1; - m_active_threads.reset(tid); - assert( m_thread[tid]!= NULL ); - did_exit=true; + // this code checks if this warp has finished executing and can be reclaimed + if( m_warp[warp_id].hardware_done() && !m_scoreboard->pendingWrites(warp_id) && !m_warp[warp_id].done_exit() ) { + bool did_exit=false; + for( unsigned t=0; t<m_config->warp_size;t++) { + unsigned tid=warp_id*m_config->warp_size+t; + if( m_threadState[tid].m_active == true ) { + m_threadState[tid].m_active = false; + unsigned cta_id = m_warp[warp_id].get_cta_id(); + register_cta_thread_exit(cta_id); + m_not_completed -= 1; + m_active_threads.reset(tid); + assert( m_thread[tid]!= NULL ); + did_exit=true; + } } + if( did_exit ) + m_warp[warp_id].set_done_exit(); } - if( did_exit ) - m_warp[warp_id].set_done_exit(); - } - // this code fetches instructions from the i-cache or generates memory requests - if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) { - address_type pc = m_warp[warp_id].get_pc(); - address_type ppc = pc + PROGRAM_MEM_START; - unsigned nbytes=16; - unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz()-1); - if( (offset_in_block+nbytes) > m_config->m_L1I_config.get_line_sz() ) - nbytes = (m_config->m_L1I_config.get_line_sz()-offset_in_block); + // this code fetches instructions from the i-cache or generates memory requests + if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) { + address_type pc = m_warp[warp_id].get_pc(); + address_type ppc = pc + PROGRAM_MEM_START; + unsigned nbytes=16; + unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz()-1); + if( (offset_in_block+nbytes) > m_config->m_L1I_config.get_line_sz() ) + nbytes = (m_config->m_L1I_config.get_line_sz()-offset_in_block); - // TODO: replace with use of allocator - // mem_fetch *mf = m_mem_fetch_allocator->alloc() - mem_access_t acc(INST_ACC_R,ppc,nbytes,false); - mem_fetch *mf = new mem_fetch(acc, - NULL/*we don't have an instruction yet*/, - READ_PACKET_SIZE, - warp_id, - m_sid, - m_tpc, - m_memory_config ); - std::list<cache_event> events; - enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, gpu_sim_cycle+gpu_tot_sim_cycle,events); - if( status == MISS ) { - m_last_warp_fetched=warp_id; - m_warp[warp_id].set_imiss_pending(); - m_warp[warp_id].set_last_fetch(gpu_sim_cycle); - } else if( status == HIT ) { - m_last_warp_fetched=warp_id; - m_inst_fetch_buffer = ifetch_buffer_t(pc,nbytes,warp_id); - m_warp[warp_id].set_last_fetch(gpu_sim_cycle); - delete mf; - } else { - m_last_warp_fetched=warp_id; - assert( status == RESERVATION_FAIL ); - delete mf; + // TODO: replace with use of allocator + // mem_fetch *mf = m_mem_fetch_allocator->alloc() + mem_access_t acc(INST_ACC_R,ppc,nbytes,false); + mem_fetch *mf = new mem_fetch(acc, + NULL/*we don't have an instruction yet*/, + READ_PACKET_SIZE, + warp_id, + m_sid, + m_tpc, + m_memory_config ); + std::list<cache_event> events; + enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, gpu_sim_cycle+gpu_tot_sim_cycle,events); + if( status == MISS ) { + m_last_warp_fetched=warp_id; + m_warp[warp_id].set_imiss_pending(); + m_warp[warp_id].set_last_fetch(gpu_sim_cycle); + } else if( status == HIT ) { + m_last_warp_fetched=warp_id; + m_inst_fetch_buffer = ifetch_buffer_t(pc,nbytes,warp_id); + m_warp[warp_id].set_last_fetch(gpu_sim_cycle); + delete mf; + } else { + m_last_warp_fetched=warp_id; + assert( status == RESERVATION_FAIL ); + delete mf; + } + break; } - break; } } } m_L1I->cycle(); - - if( m_L1I->access_ready() ) { - mem_fetch *mf = m_L1I->next_access(); - m_warp[mf->get_wid()].clear_imiss_pending(); - delete mf; - } } void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) @@ -680,7 +686,7 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* { warp_inst_t** pipe_reg = pipe_reg_set.get_free(); assert(pipe_reg); - + m_warp[warp_id].ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information @@ -688,7 +694,7 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; func_exec_inst( **pipe_reg ); if( next_inst->op == BARRIER_OP ){ - m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); + m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id,const_cast<warp_inst_t*> (next_inst)); }else if( next_inst->op == MEMORY_BARRIER_OP ){ @@ -731,21 +737,21 @@ shd_warp_t& scheduler_unit::warp(int i){ * limit this number. If the number if < m_supervised_warps.size(), then only * the warps with highest RR priority will be placed in the result_list. */ -template < class T > + template < class T > void scheduler_unit::order_lrr( std::vector< T >& result_list, - const typename std::vector< T >& input_list, - const typename std::vector< T >::const_iterator& last_issued_from_input, - unsigned num_warps_to_add ) + const typename std::vector< T >& input_list, + const typename std::vector< T >::const_iterator& last_issued_from_input, + unsigned num_warps_to_add ) { assert( num_warps_to_add <= input_list.size() ); result_list.clear(); typename std::vector< T >::const_iterator iter = ( last_issued_from_input == input_list.end() ) ? input_list.begin() - : last_issued_from_input + 1; + : last_issued_from_input + 1; for ( unsigned count = 0; - count < num_warps_to_add; - ++iter, ++count) { + count < num_warps_to_add; + ++iter, ++count) { if ( iter == input_list.end() ) { iter = input_list.begin(); } @@ -764,13 +770,13 @@ void scheduler_unit::order_lrr( std::vector< T >& result_list, * with the oldest warps having the most priority, then the priority_function * would compare the age of the two warps. */ -template < class T > + template < class T > void scheduler_unit::order_by_priority( std::vector< T >& result_list, - const typename std::vector< T >& input_list, - const typename std::vector< T >::const_iterator& last_issued_from_input, - unsigned num_warps_to_add, - OrderingType ordering, - bool (*priority_func)(T lhs, T rhs) ) + const typename std::vector< T >& input_list, + const typename std::vector< T >::const_iterator& last_issued_from_input, + unsigned num_warps_to_add, + OrderingType ordering, + bool (*priority_func)(T lhs, T rhs) ) { assert( num_warps_to_add <= input_list.size() ); result_list.clear(); |
