diff options
| author | mkhairy <[email protected]> | 2021-05-18 14:04:11 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-05-18 14:04:11 -0400 |
| commit | 585dcf5dc05d6343314600114ebcea8c719e7423 (patch) | |
| tree | bff77b423ca7b88dff608d071240cd1af5e24213 /src | |
| parent | c51350d4a02a222663521ae6ca380970884b39e2 (diff) | |
| parent | 7d9a12fb096db5492924ec32a96c9052552e8579 (diff) | |
Merge pull request #12 from barnes88/sub_core_devel
sub_core_model operand collector unit partitioning
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.h | 56 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 177 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 48 |
3 files changed, 202 insertions, 79 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index c012de0..982e416 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1291,6 +1291,7 @@ class register_set { } m_name = name; } + const char *get_name() { return m_name; } bool has_free() { for (unsigned i = 0; i < regs.size(); i++) { if (regs[i]->empty()) { @@ -1315,7 +1316,35 @@ class register_set { } return false; } + bool has_ready(bool sub_core_model, unsigned reg_id) { + if (!sub_core_model) return has_ready(); + assert(reg_id < regs.size()); + return (not regs[reg_id]->empty()); + } + unsigned get_ready_reg_id() { + // for sub core model we need to figure which reg_id has the ready warp + // this function should only be called if has_ready() was true + assert(has_ready()); + warp_inst_t **ready; + ready = NULL; + unsigned reg_id; + for (unsigned i = 0; i < regs.size(); i++) { + if (not regs[i]->empty()) { + if (ready and (*ready)->get_uid() < regs[i]->get_uid()) { + // ready is oldest + } else { + ready = ®s[i]; + reg_id = i; + } + } + } + return reg_id; + } + unsigned get_schd_id(unsigned reg_id) { + assert(not regs[reg_id]->empty()); + return regs[reg_id]->get_schd_id(); + } void move_in(warp_inst_t *&src) { warp_inst_t **free = get_free(); move_warp(*free, src); @@ -1323,10 +1352,29 @@ class register_set { // void copy_in( warp_inst_t* src ){ // src->copy_contents_to(*get_free()); //} + void move_in(bool sub_core_model, unsigned reg_id, warp_inst_t *&src) { + warp_inst_t **free; + if (!sub_core_model) { + free = get_free(); + } else { + assert(reg_id < regs.size()); + free = get_free(sub_core_model, reg_id); + } + move_warp(*free, src); + } + void move_out_to(warp_inst_t *&dest) { warp_inst_t **ready = get_ready(); move_warp(dest, *ready); } + void move_out_to(bool sub_core_model, unsigned reg_id, warp_inst_t *&dest) { + if (!sub_core_model) { + return move_out_to(dest); + } + warp_inst_t **ready = get_ready(sub_core_model, reg_id); + assert(ready != NULL); + move_warp(dest, *ready); + } warp_inst_t **get_ready() { warp_inst_t **ready; @@ -1342,6 +1390,14 @@ class register_set { } return ready; } + warp_inst_t **get_ready(bool sub_core_model, unsigned reg_id) { + if (!sub_core_model) return get_ready(); + warp_inst_t **ready; + ready = NULL; + assert(reg_id < regs.size()); + if (not regs[reg_id]->empty()) ready = ®s[reg_id]; + return ready; + } void print(FILE *fp) const { fprintf(fp, "%s : @%p\n", m_name, this); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index c6e7b8f..14d9044 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -166,18 +166,15 @@ void shader_core_ctx::create_schedulers() { // must currently occur after all inputs have been initialized. std::string sched_config = m_config->gpgpu_scheduler_string; const concrete_scheduler scheduler = - sched_config.find("lrr") != std::string::npos - ? CONCRETE_SCHEDULER_LRR - : sched_config.find("two_level_active") != std::string::npos - ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE - : sched_config.find("gto") != std::string::npos - ? CONCRETE_SCHEDULER_GTO - : sched_config.find("old") != std::string::npos - ? CONCRETE_SCHEDULER_OLDEST_FIRST - : sched_config.find("warp_limiting") != - std::string::npos - ? CONCRETE_SCHEDULER_WARP_LIMITING - : NUM_CONCRETE_SCHEDULERS; + sched_config.find("lrr") != std::string::npos ? CONCRETE_SCHEDULER_LRR + : sched_config.find("two_level_active") != std::string::npos + ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE + : sched_config.find("gto") != std::string::npos ? CONCRETE_SCHEDULER_GTO + : sched_config.find("old") != std::string::npos + ? CONCRETE_SCHEDULER_OLDEST_FIRST + : sched_config.find("warp_limiting") != std::string::npos + ? CONCRETE_SCHEDULER_WARP_LIMITING + : NUM_CONCRETE_SCHEDULERS; assert(scheduler != NUM_CONCRETE_SCHEDULERS); for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++) { @@ -377,41 +374,41 @@ void shader_core_ctx::create_exec_pipeline() { // m_fu = new simd_function_unit*[m_num_function_units]; - for (int k = 0; k < m_config->gpgpu_num_sp_units; k++) { - m_fu.push_back(new sp_unit(&m_pipeline_reg[EX_WB], m_config, this)); + for (unsigned k = 0; k < m_config->gpgpu_num_sp_units; k++) { + m_fu.push_back(new sp_unit(&m_pipeline_reg[EX_WB], m_config, this, k)); m_dispatch_port.push_back(ID_OC_SP); m_issue_port.push_back(OC_EX_SP); } - for (int k = 0; k < m_config->gpgpu_num_dp_units; k++) { - m_fu.push_back(new dp_unit(&m_pipeline_reg[EX_WB], m_config, this)); + for (unsigned k = 0; k < m_config->gpgpu_num_dp_units; k++) { + m_fu.push_back(new dp_unit(&m_pipeline_reg[EX_WB], m_config, this, k)); m_dispatch_port.push_back(ID_OC_DP); m_issue_port.push_back(OC_EX_DP); } - for (int k = 0; k < m_config->gpgpu_num_int_units; k++) { - m_fu.push_back(new int_unit(&m_pipeline_reg[EX_WB], m_config, this)); + for (unsigned k = 0; k < m_config->gpgpu_num_int_units; k++) { + m_fu.push_back(new int_unit(&m_pipeline_reg[EX_WB], m_config, this, k)); m_dispatch_port.push_back(ID_OC_INT); m_issue_port.push_back(OC_EX_INT); } - for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) { - m_fu.push_back(new sfu(&m_pipeline_reg[EX_WB], m_config, this)); + for (unsigned k = 0; k < m_config->gpgpu_num_sfu_units; k++) { + m_fu.push_back(new sfu(&m_pipeline_reg[EX_WB], m_config, this, k)); m_dispatch_port.push_back(ID_OC_SFU); m_issue_port.push_back(OC_EX_SFU); } - for (int k = 0; k < m_config->gpgpu_num_tensor_core_units; k++) { - m_fu.push_back(new tensor_core(&m_pipeline_reg[EX_WB], m_config, this)); + for (unsigned k = 0; k < m_config->gpgpu_num_tensor_core_units; k++) { + m_fu.push_back(new tensor_core(&m_pipeline_reg[EX_WB], m_config, this, k)); m_dispatch_port.push_back(ID_OC_TENSOR_CORE); m_issue_port.push_back(OC_EX_TENSOR_CORE); } - for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) { for (unsigned k = 0; k < m_config->m_specialized_unit[j].num_units; k++) { m_fu.push_back(new specialized_unit( &m_pipeline_reg[EX_WB], m_config, this, SPEC_UNIT_START_ID + j, m_config->m_specialized_unit[j].name, - m_config->m_specialized_unit[j].latency)); + m_config->m_specialized_unit[j].latency, k)); m_dispatch_port.push_back(m_config->m_specialized_unit[j].ID_OC_SPEC_ID); m_issue_port.push_back(m_config->m_specialized_unit[j].OC_EX_SPEC_ID); } @@ -1669,8 +1666,15 @@ void shader_core_ctx::execute() { m_fu[n]->active_lanes_in_pipeline(); unsigned issue_port = m_issue_port[n]; register_set &issue_inst = m_pipeline_reg[issue_port]; - warp_inst_t **ready_reg = issue_inst.get_ready(); - if (issue_inst.has_ready() && m_fu[n]->can_issue(**ready_reg)) { + unsigned reg_id; + bool partition_issue = + m_config->sub_core_model && m_fu[n]->is_issue_partitioned(); + if (partition_issue) { + reg_id = m_fu[n]->get_issue_reg_id(); + } + warp_inst_t **ready_reg = issue_inst.get_ready(partition_issue, reg_id); + if (issue_inst.has_ready(partition_issue, reg_id) && + m_fu[n]->can_issue(**ready_reg)) { bool schedule_wb_now = !m_fu[n]->stallable(); int resbus = -1; if (schedule_wb_now && @@ -2112,22 +2116,32 @@ simd_function_unit::simd_function_unit(const shader_core_config *config) { m_dispatch_reg = new warp_inst_t(config); } +void simd_function_unit::issue(register_set &source_reg) { + bool partition_issue = + m_config->sub_core_model && this->is_issue_partitioned(); + source_reg.move_out_to(partition_issue, this->get_issue_reg_id(), + m_dispatch_reg); + occupied.set(m_dispatch_reg->latency); +} + sfu::sfu(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core) - : pipelined_simd_unit(result_port, config, config->max_sfu_latency, core) { + shader_core_ctx *core, unsigned issue_reg_id) + : pipelined_simd_unit(result_port, config, config->max_sfu_latency, core, + issue_reg_id) { m_name = "SFU"; } tensor_core::tensor_core(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core) + shader_core_ctx *core, unsigned issue_reg_id) : pipelined_simd_unit(result_port, config, config->max_tensor_core_latency, - core) { + core, issue_reg_id) { m_name = "TENSOR_CORE"; } void sfu::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = SFU__OP; @@ -2136,7 +2150,8 @@ void sfu::issue(register_set &source_reg) { } void tensor_core::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = TENSOR_CORE__OP; @@ -2208,34 +2223,39 @@ void tensor_core::active_lanes_in_pipeline() { } sp_unit::sp_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core) - : pipelined_simd_unit(result_port, config, config->max_sp_latency, core) { + shader_core_ctx *core, unsigned issue_reg_id) + : pipelined_simd_unit(result_port, config, config->max_sp_latency, core, + issue_reg_id) { m_name = "SP "; } specialized_unit::specialized_unit(register_set *result_port, const shader_core_config *config, shader_core_ctx *core, unsigned supported_op, - char *unit_name, unsigned latency) - : pipelined_simd_unit(result_port, config, latency, core) { + char *unit_name, unsigned latency, + unsigned issue_reg_id) + : pipelined_simd_unit(result_port, config, latency, core, issue_reg_id) { m_name = unit_name; m_supported_op = supported_op; } dp_unit::dp_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core) - : pipelined_simd_unit(result_port, config, config->max_dp_latency, core) { + shader_core_ctx *core, unsigned issue_reg_id) + : pipelined_simd_unit(result_port, config, config->max_dp_latency, core, + issue_reg_id) { m_name = "DP "; } int_unit::int_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core) - : pipelined_simd_unit(result_port, config, config->max_int_latency, core) { + shader_core_ctx *core, unsigned issue_reg_id) + : pipelined_simd_unit(result_port, config, config->max_int_latency, core, + issue_reg_id) { m_name = "INT "; } void sp_unit ::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = SP__OP; m_core->incsp_stat(m_core->get_config()->warp_size, (*ready_reg)->latency); @@ -2243,7 +2263,8 @@ void sp_unit ::issue(register_set &source_reg) { } void dp_unit ::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = DP__OP; m_core->incsp_stat(m_core->get_config()->warp_size, (*ready_reg)->latency); @@ -2251,7 +2272,8 @@ void dp_unit ::issue(register_set &source_reg) { } void specialized_unit ::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = SPECIALIZED__OP; m_core->incsp_stat(m_core->get_config()->warp_size, (*ready_reg)->latency); @@ -2259,7 +2281,8 @@ void specialized_unit ::issue(register_set &source_reg) { } void int_unit ::issue(register_set &source_reg) { - warp_inst_t **ready_reg = source_reg.get_ready(); + warp_inst_t **ready_reg = + source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = INTP__OP; m_core->incsp_stat(m_core->get_config()->warp_size, (*ready_reg)->latency); @@ -2269,7 +2292,8 @@ void int_unit ::issue(register_set &source_reg) { pipelined_simd_unit::pipelined_simd_unit(register_set *result_port, const shader_core_config *config, unsigned max_latency, - shader_core_ctx *core) + shader_core_ctx *core, + unsigned issue_reg_id) : simd_function_unit(config) { m_result_port = result_port; m_pipeline_depth = max_latency; @@ -2277,6 +2301,7 @@ pipelined_simd_unit::pipelined_simd_unit(register_set *result_port, for (unsigned i = 0; i < m_pipeline_depth; i++) m_pipeline_reg[i] = new warp_inst_t(config); m_core = core; + m_issue_reg_id = issue_reg_id; active_insts_in_pipeline = 0; } @@ -2303,7 +2328,10 @@ void pipelined_simd_unit::cycle() { void pipelined_simd_unit::issue(register_set &source_reg) { // move_warp(m_dispatch_reg,source_reg); - warp_inst_t **ready_reg = source_reg.get_ready(); + bool partition_issue = + m_config->sub_core_model && this->is_issue_partitioned(); + warp_inst_t **ready_reg = + source_reg.get_ready(partition_issue, m_issue_reg_id); m_core->incexecstat((*ready_reg)); // source_reg.move_out_to(m_dispatch_reg); simd_function_unit::issue(source_reg); @@ -2360,7 +2388,7 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt, Scoreboard *scoreboard, const shader_core_config *config, const memory_config *mem_config, shader_core_stats *stats, unsigned sid, unsigned tpc) - : pipelined_simd_unit(NULL, config, config->smem_latency, core), + : pipelined_simd_unit(NULL, config, config->smem_latency, core, 0), m_next_wb(config) { assert(config->smem_latency > 1); init(icnt, mf_allocator, core, operand_collector, scoreboard, config, @@ -2388,7 +2416,7 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt, Scoreboard *scoreboard, const shader_core_config *config, const memory_config *mem_config, shader_core_stats *stats, unsigned sid, unsigned tpc, l1_cache *new_l1d_cache) - : pipelined_simd_unit(NULL, config, 3, core), + : pipelined_simd_unit(NULL, config, 3, core, 0), m_L1D(new_l1d_cache), m_next_wb(config) { init(icnt, mf_allocator, core, operand_collector, scoreboard, config, @@ -3867,15 +3895,23 @@ void opndcoll_rfu_t::init(unsigned num_banks, shader_core_ctx *shader) { assert((m_bank_warp_shift == 5) || (m_warp_size != 32)); sub_core_model = shader->get_config()->sub_core_model; - m_num_warp_sceds = shader->get_config()->gpgpu_num_sched_per_core; - if (sub_core_model) + m_num_warp_scheds = shader->get_config()->gpgpu_num_sched_per_core; + unsigned reg_id; + if (sub_core_model) { assert(num_banks % shader->get_config()->gpgpu_num_sched_per_core == 0); + assert(m_num_warp_scheds <= m_cu.size() && + m_cu.size() % m_num_warp_scheds == 0); + } m_num_banks_per_sched = num_banks / shader->get_config()->gpgpu_num_sched_per_core; for (unsigned j = 0; j < m_cu.size(); j++) { + if (sub_core_model) { + unsigned cusPerSched = m_cu.size() / m_num_warp_scheds; + reg_id = j / cusPerSched; + } m_cu[j]->init(j, num_banks, m_bank_warp_shift, shader->get_config(), this, - sub_core_model, m_num_banks_per_sched); + sub_core_model, reg_id, m_num_banks_per_sched); } m_initialized = true; } @@ -3974,7 +4010,22 @@ void opndcoll_rfu_t::allocate_cu(unsigned port_num) { for (unsigned j = 0; j < inp.m_cu_sets.size(); j++) { std::vector<collector_unit_t> &cu_set = m_cus[inp.m_cu_sets[j]]; bool allocated = false; - for (unsigned k = 0; k < cu_set.size(); k++) { + unsigned cuLowerBound = 0; + unsigned cuUpperBound = cu_set.size(); + unsigned schd_id; + if (sub_core_model) { + // Sub core model only allocates on the subset of CUs assigned to the + // scheduler that issued + unsigned reg_id = (*inp.m_in[i]).get_ready_reg_id(); + schd_id = (*inp.m_in[i]).get_schd_id(reg_id); + assert(cu_set.size() % m_num_warp_scheds == 0 && + cu_set.size() >= m_num_warp_scheds); + unsigned cusPerSched = cu_set.size() / m_num_warp_scheds; + cuLowerBound = schd_id * cusPerSched; + cuUpperBound = cuLowerBound + cusPerSched; + assert(0 <= cuLowerBound && cuUpperBound <= cu_set.size()); + } + for (unsigned k = cuLowerBound; k < cuUpperBound; k++) { if (cu_set[k].is_free()) { collector_unit_t *cu = &cu_set[k]; allocated = cu->allocate(inp.m_in[i], inp.m_out[i]); @@ -3984,8 +4035,9 @@ void opndcoll_rfu_t::allocate_cu(unsigned port_num) { } if (allocated) break; // cu has been allocated, no need to search more. } - break; // can only service a single input, if it failed it will fail for - // others. + // break; // can only service a single input, if it failed it will fail + // for + // others. } } } @@ -4032,7 +4084,8 @@ void opndcoll_rfu_t::allocate_reads() { } bool opndcoll_rfu_t::collector_unit_t::ready() const { - return (!m_free) && m_not_ready.none() && (*m_output_register).has_free(); + return (!m_free) && m_not_ready.none() && + (*m_output_register).has_free(m_sub_core_model, m_reg_id); } void opndcoll_rfu_t::collector_unit_t::dump( @@ -4050,12 +4103,10 @@ void opndcoll_rfu_t::collector_unit_t::dump( } } -void opndcoll_rfu_t::collector_unit_t::init(unsigned n, unsigned num_banks, - unsigned log2_warp_size, - const core_config *config, - opndcoll_rfu_t *rfu, - bool sub_core_model, - unsigned banks_per_sched) { +void opndcoll_rfu_t::collector_unit_t::init( + unsigned n, unsigned num_banks, unsigned log2_warp_size, + const core_config *config, opndcoll_rfu_t *rfu, bool sub_core_model, + unsigned reg_id, unsigned banks_per_sched) { m_rfu = rfu; m_cuid = n; m_num_banks = num_banks; @@ -4063,6 +4114,7 @@ void opndcoll_rfu_t::collector_unit_t::init(unsigned n, unsigned num_banks, m_warp = new warp_inst_t(config); m_bank_warp_shift = log2_warp_size; m_sub_core_model = sub_core_model; + m_reg_id = reg_id; m_num_banks_per_sched = banks_per_sched; } @@ -4097,8 +4149,7 @@ bool opndcoll_rfu_t::collector_unit_t::allocate(register_set *pipeline_reg_set, void opndcoll_rfu_t::collector_unit_t::dispatch() { assert(m_not_ready.none()); - // move_warp(*m_output_register,m_warp); - m_output_register->move_in(m_warp); + m_output_register->move_in(m_sub_core_model, m_reg_id, m_warp); m_free = true; m_output_register = NULL; for (unsigned i = 0; i < MAX_REG_OPERANDS * 2; i++) m_src_op[i].reset(); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 6481790..8c02fd7 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -238,7 +238,10 @@ class shd_warp_t { unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; } unsigned get_warp_id() const { return m_warp_id; } - class shader_core_ctx * get_shader() { return m_shader; } + class shader_core_ctx *get_shader() { + return m_shader; + } + private: static const unsigned IBUFFER_SIZE = 2; class shader_core_ctx *m_shader; @@ -878,11 +881,13 @@ class opndcoll_rfu_t { // operand collector based register file unit } unsigned get_sp_op() const { return m_warp->sp_op; } unsigned get_id() const { return m_cuid; } // returns CU hw id + unsigned get_reg_id() const { return m_reg_id; } // modifiers void init(unsigned n, unsigned num_banks, unsigned log2_warp_size, const core_config *config, opndcoll_rfu_t *rfu, - bool m_sub_core_model, unsigned num_banks_per_sched); + bool m_sub_core_model, unsigned reg_id, + unsigned num_banks_per_sched); bool allocate(register_set *pipeline_reg, register_set *output_reg); void collect_operand(unsigned op) { m_not_ready.reset(op); } @@ -906,6 +911,7 @@ class opndcoll_rfu_t { // operand collector based register file unit unsigned m_num_banks_per_sched; bool m_sub_core_model; + unsigned m_reg_id; // if sub_core_model enabled, limit regs this cu can r/w }; class dispatch_unit_t { @@ -947,7 +953,7 @@ class opndcoll_rfu_t { // operand collector based register file unit arbiter_t m_arbiter; unsigned m_num_banks_per_sched; - unsigned m_num_warp_sceds; + unsigned m_num_warp_scheds; bool sub_core_model; // unsigned m_num_ports; @@ -1039,10 +1045,7 @@ class simd_function_unit { ~simd_function_unit() { delete m_dispatch_reg; } // modifiers - virtual void issue(register_set &source_reg) { - source_reg.move_out_to(m_dispatch_reg); - occupied.set(m_dispatch_reg->latency); - } + virtual void issue(register_set &source_reg); virtual void cycle() = 0; virtual void active_lanes_in_pipeline() = 0; @@ -1051,6 +1054,8 @@ class simd_function_unit { virtual bool can_issue(const warp_inst_t &inst) const { return m_dispatch_reg->empty() && !occupied.test(inst.latency); } + virtual bool is_issue_partitioned() = 0; + virtual unsigned get_issue_reg_id() = 0; virtual bool stallable() const = 0; virtual void print(FILE *fp) const { fprintf(fp, "%s dispatch= ", m_name.c_str()); @@ -1070,7 +1075,7 @@ class pipelined_simd_unit : public simd_function_unit { public: pipelined_simd_unit(register_set *result_port, const shader_core_config *config, unsigned max_latency, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); // modifiers virtual void cycle(); @@ -1091,6 +1096,8 @@ class pipelined_simd_unit : public simd_function_unit { virtual bool can_issue(const warp_inst_t &inst) const { return simd_function_unit::can_issue(inst); } + virtual bool is_issue_partitioned() = 0; + unsigned get_issue_reg_id() { return m_issue_reg_id; } virtual void print(FILE *fp) const { simd_function_unit::print(fp); for (int s = m_pipeline_depth - 1; s >= 0; s--) { @@ -1106,6 +1113,8 @@ class pipelined_simd_unit : public simd_function_unit { warp_inst_t **m_pipeline_reg; register_set *m_result_port; class shader_core_ctx *m_core; + unsigned m_issue_reg_id; // if sub_core_model is enabled we can only issue + // from a subset of operand collectors unsigned active_insts_in_pipeline; }; @@ -1113,7 +1122,7 @@ class pipelined_simd_unit : public simd_function_unit { class sfu : public pipelined_simd_unit { public: sfu(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { switch (inst.op) { case SFU_OP: @@ -1129,12 +1138,13 @@ class sfu : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } }; class dp_unit : public pipelined_simd_unit { public: dp_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { switch (inst.op) { case DP_OP: @@ -1146,12 +1156,13 @@ class dp_unit : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } }; class tensor_core : public pipelined_simd_unit { public: tensor_core(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { switch (inst.op) { case TENSOR_CORE_OP: @@ -1163,12 +1174,13 @@ class tensor_core : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } }; class int_unit : public pipelined_simd_unit { public: int_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { switch (inst.op) { case SFU_OP: @@ -1194,12 +1206,13 @@ class int_unit : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } }; class sp_unit : public pipelined_simd_unit { public: sp_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core); + shader_core_ctx *core, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { switch (inst.op) { case SFU_OP: @@ -1223,13 +1236,14 @@ class sp_unit : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } }; class specialized_unit : public pipelined_simd_unit { public: specialized_unit(register_set *result_port, const shader_core_config *config, shader_core_ctx *core, unsigned supported_op, - char *unit_name, unsigned latency); + char *unit_name, unsigned latency, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { if (inst.op != m_supported_op) { return false; @@ -1238,6 +1252,7 @@ class specialized_unit : public pipelined_simd_unit { } virtual void active_lanes_in_pipeline(); virtual void issue(register_set &source_reg); + bool is_issue_partitioned() { return true; } private: unsigned m_supported_op; @@ -1259,6 +1274,7 @@ class ldst_unit : public pipelined_simd_unit { // modifiers virtual void issue(register_set &inst); + bool is_issue_partitioned() { return false; } virtual void cycle(); void fill(mem_fetch *mf); @@ -2133,8 +2149,8 @@ class shader_core_ctx : public core_t { friend class TwoLevelScheduler; friend class LooseRoundRobbinScheduler; virtual void issue_warp(register_set &warp, const warp_inst_t *pI, - const active_mask_t &active_mask, unsigned warp_id, - unsigned sch_id); + const active_mask_t &active_mask, unsigned warp_id, + unsigned sch_id); void create_front_pipeline(); void create_schedulers(); |
