aboutsummaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/shader.h')
-rw-r--r--src/gpgpu-sim/shader.h206
1 files changed, 168 insertions, 38 deletions
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index c74fa96..952651e 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -259,6 +259,27 @@ class shader_core_ctx;
class shader_core_config;
class shader_core_stats;
+enum scheduler_prioritization_type
+{
+ SCHEDULER_PRIORITIZATION_LRR = 0, // Loose Round Robin
+ SCHEDULER_PRIORITIZATION_SRR, // Strict Round Robin
+ SCHEDULER_PRIORITIZATION_GTO, // Greedy Then Oldest
+ SCHEDULER_PRIORITIZATION_GTLRR, // Greedy Then Loose Round Robin
+ SCHEDULER_PRIORITIZATION_GTY, // Greedy Then Youngest
+ SCHEDULER_PRIORITIZATION_OLDEST, // Oldest First
+ SCHEDULER_PRIORITIZATION_YOUNGEST, // Youngest First
+};
+
+// Each of these corresponds to a string value in the gpgpsim.config file
+// For example - to specify the LRR scheudler the config must contain lrr
+enum concrete_scheduler
+{
+ CONCRETE_SCHEDULER_LRR = 0,
+ CONCRETE_SCHEDULER_GTO,
+ CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE,
+ NUM_CONCRETE_SCHEDULERS
+};
+
class scheduler_unit { //this can be copied freely, so can be used in std containers.
public:
scheduler_unit(shader_core_stats* stats, shader_core_ctx* shader,
@@ -266,21 +287,74 @@ public:
std::vector<shd_warp_t>* warp,
register_set* sp_out,
register_set* sfu_out,
- register_set* mem_out)
- : supervised_warps(), m_last_sup_id_issued(0), m_stats(stats), m_shader(shader),
+ register_set* mem_out,
+ int id)
+ : m_supervised_warps(), m_stats(stats), m_shader(shader),
m_scoreboard(scoreboard), m_simt_stack(simt), /*m_pipeline_reg(pipe_regs),*/ m_warp(warp),
- m_sp_out(sp_out),m_sfu_out(sfu_out),m_mem_out(mem_out){}
+ m_sp_out(sp_out),m_sfu_out(sfu_out),m_mem_out(mem_out), m_id(id){}
virtual ~scheduler_unit(){}
virtual void add_supervised_warp_id(int i) {
- supervised_warps.push_back(i);
+ m_supervised_warps.push_back(&warp(i));
+ }
+ virtual void done_adding_supervised_warps() {
+ m_last_supervised_issued = m_supervised_warps.end();
}
- virtual void cycle()=0;
+
+ // The core scheduler cycle method is meant to be common between
+ // all the derived schedulers. The scheduler's behaviour can be
+ // modified by changing the contents of the m_next_cycle_prioritized_warps list.
+ void cycle();
+
+ // These are some common ordering fucntions that the
+ // higher order schedulers can take advantage of
+ template < typename T >
+ void order_lrr( typename 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 );
+
+ enum OrderingType
+ {
+ // The item that issued last is prioritized first then the sorted result
+ // of the priority_function
+ ORDERING_GREEDY_THEN_PRIORITY_FUNC = 0,
+ // No greedy scheduling based on last to issue. Only the priority function determines
+ // priority
+ ORDERED_PRIORITY_FUNC_ONLY,
+ NUM_ORDERING,
+ };
+ template < typename U >
+ void order_by_priority( std::vector< U >& result_list,
+ const typename std::vector< U >& input_list,
+ const typename std::vector< U >::const_iterator& last_issued_from_input,
+ unsigned num_warps_to_add,
+ OrderingType age_ordering,
+ bool (*priority_func)(U lhs, U rhs) );
+ static bool sort_warps_by_oldest_dynamic_id(shd_warp_t* lhs, shd_warp_t* rhs);
+
+ // Derived classes can override this function to populate
+ // m_supervised_warps with their scheduling policies
+ virtual void order_warps() = 0;
+
+protected:
+ virtual void do_on_warp_issued( unsigned warp_id,
+ unsigned num_issued,
+ const std::vector< shd_warp_t* >::const_iterator& prioritized_iter );
+ inline int get_sid() const;
protected:
shd_warp_t& warp(int i);
- std::vector<int> supervised_warps;
- int m_last_sup_id_issued;
+ // This is the prioritized warp list that is looped over each cycle to determine
+ // which warp gets to issue.
+ std::vector< shd_warp_t* > m_next_cycle_prioritized_warps;
+ // The m_supervised_warps list is all the warps this scheduler is supposed to
+ // arbitrate between. This is useful in systems where there is more than
+ // one warp scheduler. In a single scheduler system, this is simply all
+ // the warps assigned to this core.
+ std::vector< shd_warp_t* > m_supervised_warps;
+ // This is the iterator pointer to the last supervised warp you issued
+ std::vector< shd_warp_t* >::const_iterator m_last_supervised_issued;
shader_core_stats *m_stats;
shader_core_ctx* m_shader;
// these things should become accessors: but would need a bigger rearchitect of how shader_core_ctx interacts with its parts.
@@ -291,45 +365,89 @@ protected:
register_set* m_sp_out;
register_set* m_sfu_out;
register_set* m_mem_out;
+
+ int m_id;
};
-class LooseRoundRobbinScheduler : public scheduler_unit {
+class lrr_scheduler : public scheduler_unit {
public:
- LooseRoundRobbinScheduler (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)
- : scheduler_unit (stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out){}
- virtual ~LooseRoundRobbinScheduler () {}
- virtual void cycle ();
+ lrr_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 )
+ : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ){}
+ virtual ~lrr_scheduler () {}
+ virtual void order_warps ();
+ virtual void done_adding_supervised_warps() {
+ m_last_supervised_issued = m_supervised_warps.end();
+ }
};
+class gto_scheduler : public scheduler_unit {
+public:
+ gto_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 )
+ : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ){}
+ virtual ~gto_scheduler () {}
+ virtual void order_warps ();
+ virtual void done_adding_supervised_warps() {
+ m_last_supervised_issued = m_supervised_warps.begin();
+ }
+
+};
-class TwoLevelScheduler : public scheduler_unit {
+
+class two_level_active_scheduler : public scheduler_unit {
public:
- TwoLevelScheduler (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,
- unsigned maw)
- : scheduler_unit (stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out),
- activeWarps(),
- pendingWarps(){
- maxActiveWarps = maw;
- }
- virtual ~TwoLevelScheduler () {}
- virtual void cycle ();
- virtual void add_supervised_warp_id(int i) {
- pendingWarps.push_back(i);
+ two_level_active_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_str )
+ : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ),
+ m_pending_warps()
+ {
+ int ret = sscanf( config_str,
+ "two_level_active:%d:%d:%d",
+ &m_max_active_warps,
+ (int*)&m_inner_level_prioritization,
+ (int*)&m_outer_level_prioritization );
+ assert( 3 == ret );
+ }
+ virtual ~two_level_active_scheduler () {}
+ virtual void order_warps();
+ void add_supervised_warp_id(int i) {
+ if ( m_next_cycle_prioritized_warps.size() < m_max_active_warps ) {
+ m_next_cycle_prioritized_warps.push_back( &warp(i) );
+ } else {
+ m_pending_warps.push_back(&warp(i));
+ }
}
+ virtual void done_adding_supervised_warps() {
+ m_last_supervised_issued = m_supervised_warps.begin();
+ }
+
+protected:
+ virtual void do_on_warp_issued( unsigned warp_id,
+ unsigned num_issued,
+ const std::vector< shd_warp_t* >::const_iterator& prioritized_iter );
+
private:
- unsigned maxActiveWarps;
- std::list<int> activeWarps;
- std::list<int> pendingWarps;
+ std::deque< shd_warp_t* > m_pending_warps;
+ scheduler_prioritization_type m_inner_level_prioritization;
+ scheduler_prioritization_type m_outer_level_prioritization;
+ unsigned m_max_active_warps;
};
@@ -1158,6 +1276,7 @@ struct shader_core_config : public core_config
//Shader core resources
unsigned gpgpu_shader_registers;
int gpgpu_warpdistro_shader;
+ int gpgpu_warp_issue_shader;
unsigned gpgpu_num_reg_banks;
bool gpgpu_reg_bank_use_warp_id;
bool gpgpu_local_mem_map;
@@ -1324,7 +1443,7 @@ public:
gpgpu_n_shmem_bank_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_shader_dynamic_warp_issue_distro.resize( config->num_shader() );
-
+ m_shader_warp_slot_issue_distro.resize( config->num_shader() );
}
void new_grid()
@@ -1342,10 +1461,18 @@ public:
return m_shader_dynamic_warp_issue_distro;
}
+ const std::vector< std::vector<unsigned> >& get_warp_slot_issue() const
+ {
+ return m_shader_warp_slot_issue_distro;
+ }
+
private:
const shader_core_config *m_config;
// Counts the instructions issued for each dynamic warp.
std::vector< std::vector<unsigned> > m_shader_dynamic_warp_issue_distro;
+ std::vector<unsigned> m_last_shader_dynamic_warp_issue_distro;
+ std::vector< std::vector<unsigned> > m_shader_warp_slot_issue_distro;
+ std::vector<unsigned> m_last_shader_warp_slot_issue_distro;
friend class power_stat_t;
friend class shader_core_ctx;
@@ -1750,4 +1877,7 @@ private:
simt_core_cluster *m_cluster;
};
+
+inline int scheduler_unit::get_sid() const { return m_shader->get_sid(); }
+
#endif /* SHADER_H */