diff options
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 136 |
1 files changed, 97 insertions, 39 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index bf6c9c0..ffbb0c6 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1192,12 +1192,20 @@ warp_inst_t *shader_core_ctx::issue_warp(register_set &pipe_reg_set, m_stats->shader_cycle_distro[2 + (*pipe_reg)->active_count()]++; // Compute SIMD set assignments before functional execution if (m_config->gpgpu_simd_partitioning) { - if (m_config->gpgpu_enable_compaction) - (*pipe_reg)->compute_simd_sets_compacted( - m_config->gpgpu_num_simd_sets, m_config->simd_set_width, 0); - else - (*pipe_reg)->compute_simd_sets(m_config->gpgpu_num_simd_sets, - m_config->simd_set_width); + switch (m_config->gpgpu_compaction_mode) { + case 1: // xor-static + (*pipe_reg)->compute_simd_sets_xor_static( + m_config->gpgpu_num_simd_sets, m_config->simd_set_width, 0); + break; + case 2: // full + (*pipe_reg)->compute_simd_sets_compacted( + m_config->gpgpu_num_simd_sets, m_config->simd_set_width, 0); + break; + default: // 0 = none + (*pipe_reg)->compute_simd_sets(m_config->gpgpu_num_simd_sets, + m_config->simd_set_width); + break; + } } func_exec_inst(**pipe_reg); @@ -1317,12 +1325,22 @@ void shader_core_ctx::co_issue_warp(warp_inst_t *composite, m_warp[warp_id]->get_streamID()); // Compute SIMD sets for the co-issued instruction - if (m_config->gpgpu_enable_compaction) - temp_inst.compute_simd_sets_compacted(m_config->gpgpu_num_simd_sets, - m_config->simd_set_width, start_set); - else - temp_inst.compute_simd_sets(m_config->gpgpu_num_simd_sets, - m_config->simd_set_width); + switch (m_config->gpgpu_compaction_mode) { + case 1: // xor-static + temp_inst.compute_simd_sets_xor_static(m_config->gpgpu_num_simd_sets, + m_config->simd_set_width, + start_set); + break; + case 2: // full + temp_inst.compute_simd_sets_compacted(m_config->gpgpu_num_simd_sets, + m_config->simd_set_width, + start_set); + break; + default: // 0 = none + temp_inst.compute_simd_sets(m_config->gpgpu_num_simd_sets, + m_config->simd_set_width); + break; + } // Functional execution for the co-issued warp's threads func_exec_inst(temp_inst); @@ -1951,18 +1969,27 @@ void scheduler_unit::cycle() { unsigned cand_sets_needed; bool can_co_issue; - if (m_shader->m_config->gpgpu_enable_compaction) { - // With compaction: just count sets needed, no overlap check + if (m_shader->m_config->gpgpu_compaction_mode == 2) { + // Full compaction: just count sets needed, no overlap check. + // Compacted placement uses start_set, so no two sets ever alias. unsigned cand_active = cand_mask.count(); cand_sets_needed = (cand_active + set_width - 1) / set_width; can_co_issue = (cand_sets_needed <= available_sets); } else { - // Without compaction: build temp sets and check overlap + // No compaction or XOR-static: build temp sets with the selected + // mapping and check set-level overlap vs. primary. warp_inst_t cand_temp(m_shader->m_config); cand_temp = *cand_inst; cand_temp.issue(cand_mask, cand_warp_id, 0, 0, 0, 0); - cand_temp.compute_simd_sets(m_shader->m_config->gpgpu_num_simd_sets, - m_shader->m_config->simd_set_width); + if (m_shader->m_config->gpgpu_compaction_mode == 1) { + cand_temp.compute_simd_sets_xor_static( + m_shader->m_config->gpgpu_num_simd_sets, + m_shader->m_config->simd_set_width); + } else { + cand_temp.compute_simd_sets( + m_shader->m_config->gpgpu_num_simd_sets, + m_shader->m_config->simd_set_width); + } can_co_issue = !warp_inst_t::simd_sets_overlap( co_issue_composite->get_simd_sets(), @@ -5152,6 +5179,39 @@ void opndcoll_rfu_t::allocate_cu(unsigned port_num) { } } +void opndcoll_rfu_t::deliver_operand(op_t &op) { + unsigned cu = op.get_oc_id(); + unsigned operand = op.get_operand(); + m_cu[cu]->collect_operand(operand); + if (m_shader->get_config()->gpgpu_clock_gated_reg_file) { + unsigned active_count = 0; + for (unsigned i = 0; i < m_shader->get_config()->warp_size; + i = i + m_shader->get_config()->n_regfile_gating_group) { + for (unsigned j = 0; + j < m_shader->get_config()->n_regfile_gating_group; j++) { + if (op.get_active_mask().test(i + j)) { + active_count += m_shader->get_config()->n_regfile_gating_group; + break; + } + } + } + m_shader->incregfile_reads(active_count); + } else { + m_shader->incregfile_reads( + m_shader->get_config()->warp_size); // op.get_active_count(); + } +} + +void opndcoll_rfu_t::drain_pending_operands() { + unsigned long long now = m_shader->get_gpu()->gpu_sim_cycle + + m_shader->get_gpu()->gpu_tot_sim_cycle; + while (!m_pending_operands.empty() && + m_pending_operands.front().cycle_ready <= now) { + deliver_operand(m_pending_operands.front().op); + m_pending_operands.pop_front(); + } +} + void opndcoll_rfu_t::allocate_reads() { // process read requests that do not have conflicts std::list<op_t> allocated = m_arbiter.allocate_reads(); @@ -5166,28 +5226,26 @@ void opndcoll_rfu_t::allocate_reads() { m_arbiter.allocate_for_read(bank, rr); read_ops[bank] = rr; } - std::map<unsigned, op_t>::iterator r; - for (r = read_ops.begin(); r != read_ops.end(); ++r) { - op_t &op = r->second; - unsigned cu = op.get_oc_id(); - unsigned operand = op.get_operand(); - m_cu[cu]->collect_operand(operand); - if (m_shader->get_config()->gpgpu_clock_gated_reg_file) { - unsigned active_count = 0; - for (unsigned i = 0; i < m_shader->get_config()->warp_size; - i = i + m_shader->get_config()->n_regfile_gating_group) { - for (unsigned j = 0; j < m_shader->get_config()->n_regfile_gating_group; - j++) { - if (op.get_active_mask().test(i + j)) { - active_count += m_shader->get_config()->n_regfile_gating_group; - break; - } - } - } - m_shader->incregfile_reads(active_count); - } else { - m_shader->incregfile_reads( - m_shader->get_config()->warp_size); // op.get_active_count()); + + const unsigned latency = + m_shader->get_config()->gpgpu_opndcoll_read_latency; + if (latency == 0) { + // Current behavior: deliver immediately, no queue. Bit-identical + // to the pre-Change-3 tip. + for (std::map<unsigned, op_t>::iterator r = read_ops.begin(); + r != read_ops.end(); ++r) { + deliver_operand(r->second); + } + } else { + // Enqueue; drain will deliver on `now + latency` or later. + unsigned long long now = m_shader->get_gpu()->gpu_sim_cycle + + m_shader->get_gpu()->gpu_tot_sim_cycle; + for (std::map<unsigned, op_t>::iterator r = read_ops.begin(); + r != read_ops.end(); ++r) { + pending_operand_t pend; + pend.op = r->second; + pend.cycle_ready = now + latency; + m_pending_operands.push_back(pend); } } } |
