summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.cc
diff options
context:
space:
mode:
authorTim Rogers <[email protected]>2013-07-06 12:22:34 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:50:58 -0700
commit7da201cb86702aca80407b94858c380fd90aba38 (patch)
tree5ad4d81a260d9110679c03b9eb34bf57e14572f5 /src/gpgpu-sim/shader.cc
parentded72b7697f0244aa789e25330b58674797929b0 (diff)
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]
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
-rw-r--r--src/gpgpu-sim/shader.cc98
1 files changed, 79 insertions, 19 deletions
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;
- }
- }
+ 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);
+ 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<shd_warp_t>* 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()
{
}