From 7da201cb86702aca80407b94858c380fd90aba38 Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Sat, 6 Jul 2013 12:22:34 -0800 Subject: Integrating changes from my personal branch. Main contribution is a static warp limiting scheduler. There is also some minor cleanup to the heirarchy of the cache code and removal some excessively long lines Review ID: 36001 lgtm: 1 [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 16580] --- src/gpgpu-sim/shader.cc | 100 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 20 deletions(-) (limited to 'src/gpgpu-sim/shader.cc') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 767fb36..5bda78c 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -50,6 +50,7 @@ #define PRIORITIZE_MSHR_OVER_WB 1 #define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) ///////////////////////////////////////////////////////////////////////////// @@ -131,6 +132,8 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE : sched_config.find("gto") != std::string::npos ? CONCRETE_SCHEDULER_GTO : + sched_config.find("warp_limiting") != std::string::npos ? + CONCRETE_SCHEDULER_WARP_LIMITING: NUM_CONCRETE_SCHEDULERS; assert ( scheduler != NUM_CONCRETE_SCHEDULERS ); @@ -180,6 +183,21 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, ) ); break; + case CONCRETE_SCHEDULER_WARP_LIMITING: + schedulers.push_back( + new swl_scheduler( m_stats, + this, + m_scoreboard, + m_simt_stack, + &m_warp, + &m_pipeline_reg[ID_OC_SP], + &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_MEM], + i, + config->gpgpu_scheduler_string + ) + ); + break; default: abort(); }; @@ -903,7 +921,13 @@ void scheduler_unit::do_on_warp_issued( unsigned warp_id, bool scheduler_unit::sort_warps_by_oldest_dynamic_id(shd_warp_t* lhs, shd_warp_t* rhs) { if (rhs && lhs) { - return lhs->get_dynamic_warp_id() < rhs->get_dynamic_warp_id(); + if ( lhs->done_exit() || lhs->waiting() ) { + return false; + } else if ( rhs->done_exit() || rhs->waiting() ) { + return true; + } else { + return lhs->get_dynamic_warp_id() < rhs->get_dynamic_warp_id(); + } } else { return lhs < rhs; } @@ -950,32 +974,32 @@ two_level_active_scheduler::do_on_warp_issued( unsigned warp_id, void two_level_active_scheduler::order_warps() { - //Move waiting warps to m_pending_warps + //Move waiting warps to m_pending_warps unsigned num_demoted = 0; - for ( std::vector< shd_warp_t* >::iterator iter = m_next_cycle_prioritized_warps.begin(); - iter != m_next_cycle_prioritized_warps.end(); ) { - bool waiting = (*iter)->waiting(); - for (int i=0; i<4; i++){ - const warp_inst_t* inst = (*iter)->ibuffer_next_inst(); - //Is the instruction waiting on a long operation? - if ( inst && inst->in[i] > 0 && this->m_scoreboard->islongop((*iter)->get_warp_id(), inst->in[i])){ - waiting = true; - } - } - - if( waiting ) { - m_pending_warps.push_back(*iter); - iter = m_next_cycle_prioritized_warps.erase(iter); + for ( std::vector< shd_warp_t* >::iterator iter = m_next_cycle_prioritized_warps.begin(); + iter != m_next_cycle_prioritized_warps.end(); ) { + bool waiting = (*iter)->waiting(); + for (int i=0; i<4; i++){ + const warp_inst_t* inst = (*iter)->ibuffer_next_inst(); + //Is the instruction waiting on a long operation? + if ( inst && inst->in[i] > 0 && this->m_scoreboard->islongop((*iter)->get_warp_id(), inst->in[i])){ + waiting = true; + } + } + + if( waiting ) { + m_pending_warps.push_back(*iter); + iter = m_next_cycle_prioritized_warps.erase(iter); SCHED_DPRINTF( "DEMOTED warp_id=%d, dynamic_warp_id=%d\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); ++num_demoted; - } else { + } else { ++iter; } - } + } - //If there is space in m_next_cycle_prioritized_warps, promote the next m_pending_warps + //If there is space in m_next_cycle_prioritized_warps, promote the next m_pending_warps unsigned num_promoted = 0; if ( SCHEDULER_PRIORITIZATION_SRR == m_outer_level_prioritization ) { while ( m_next_cycle_prioritized_warps.size() < m_max_active_warps ) { @@ -985,7 +1009,7 @@ void two_level_active_scheduler::order_warps() (m_next_cycle_prioritized_warps.back())->get_warp_id(), (m_next_cycle_prioritized_warps.back())->get_dynamic_warp_id() ); ++num_promoted; - } + } } else { fprintf( stderr, "Unimplemented m_outer_level_prioritization: %d\n", @@ -995,6 +1019,42 @@ void two_level_active_scheduler::order_warps() assert( num_promoted == num_demoted ); } +swl_scheduler::swl_scheduler ( shader_core_stats* stats, shader_core_ctx* shader, + Scoreboard* scoreboard, simt_stack** simt, + std::vector* warp, + register_set* sp_out, + register_set* sfu_out, + register_set* mem_out, + int id, + char* config_string ) + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ) +{ + int ret = sscanf( config_string, + "warp_limiting:%d:%d", + (int*)&m_prioritization, + &m_num_warps_to_limit + ); + assert( 2 == ret ); + // Currently only GTO is implemented + assert( m_prioritization == SCHEDULER_PRIORITIZATION_GTO ); + assert( m_num_warps_to_limit <= shader->get_config()->max_warps_per_shader ); +} + +void swl_scheduler::order_warps() +{ + if ( SCHEDULER_PRIORITIZATION_GTO == m_prioritization ) { + order_by_priority( m_next_cycle_prioritized_warps, + m_supervised_warps, + m_last_supervised_issued, + MIN( m_num_warps_to_limit, m_supervised_warps.size() ), + ORDERING_GREEDY_THEN_PRIORITY_FUNC, + scheduler_unit::sort_warps_by_oldest_dynamic_id ); + } else { + fprintf(stderr, "swl_scheduler m_prioritization = %d\n", m_prioritization); + abort(); + } +} + void shader_core_ctx::read_operands() { } -- cgit v1.3