diff options
| author | Tim Rogers <[email protected]> | 2013-02-20 22:19:30 -0800 |
|---|---|---|
| committer | Andrew Boktor <[email protected]> | 2014-08-14 13:50:05 -0700 |
| commit | dac99ef22b4d0e238782731398626fdcf6e5a3a6 (patch) | |
| tree | 95d72c29deaa08c567db5c26af95552bb486c5c7 /src/gpgpu-sim/shader.h | |
| parent | a37b03ced9c3f2a1ea832144a3d8087148ec77de (diff) | |
Merging
//depot/gpgpu_sim_research/fermi_tim/...
to //depot/gpgpu_sim_research/fermi/...
Integrating CLs up to 15295. Descriptions of these CL's are included.
***
A couple changes to aeriel-vision for warp issue plot support
***
More arielvision changes to support the variable-entry length stacked bar chart
***
Properly printing the right resolution of dynamic warp ids
***.
Generalized the scheduler code and added detailed statistics for which warps issue each cycle.
Verified the execution of the LRR scheduler - still have to get the two level scheduler to work.
***
Implementing the 2lvl scehduler has it has been originally coded.
LRR on both the inner and outer levels
***
Adding in a debug tracing system to GPGPU-Sim.
I am sick of writing debug code - then having to comment out, ifdef out or delete it to checkin.
This also allows for print streams so the user can decided which traces they would like to see.
Every print in GPGPU-Sim should go through this system - then it will be really easy to only get the information you want and more importantly people will (a) write and (b) checkin code that actually profiles what they are building.
Reading tracefiles is superiour in many ways to single stepping since you can print the world and just vet the logfile for what you need.
This also fascilitates advice from the Debugging Rules! book which states that you should never throw away a debugging tool. Having debug prints that don't get thrown away is big.
***
Allowing the trace to be specified in the Make.
Run Make TRACE=0 to compile the code without any traces
***
Allowing prints from the performance sim to get the actual ptx instruction text
***
Getting the two level scheduler to actaully work...
What is released in fermi does not work at all - it effectively performs "static warp limit" from my CCWS paper.
Warps are never demoted from the active list since the functionality checking to see if they are waiting on a longop is completly broken.
Maybe if the original author had access to the tracing functions this would not have happened.
The islongop test was completely broken. It did not mark the register as used, it marked the register number in the instruction as used.
For example if this instruction was creating a long op:
ld r6 [r1]
It would mark register 0 as waiting for a long op (since it is register 0 of the two registers in this instruction), not register 6.
Additionally, whenever ANY instruction from a warp releases registers, ALL the longops being tracked for this warp get cleared....
The only way anyone ever thought this worked is if they did not test it....
***
Reworking the warp schedulers to share common code.
Making the GTX480 use gto by default. I am not sure wht they really use, but it really can't be LRR.
Also adding in a new file for custom shared trace defines. These are useful when you want a print that has some
additional criteria or information printed.
Verified that the schedulers all work to a first order based on traces.
***
Making it so you can run the stats collection scripts from any directory.
Also allow the caller to specify a stats file instead of just assume its always the same one
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 15296]
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 */ |
