diff options
Diffstat (limited to 'src/gpgpu-sim/shader.h')
| -rw-r--r-- | src/gpgpu-sim/shader.h | 206 |
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 */ |
