summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
-rw-r--r--src/gpgpu-sim/shader.cc136
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);
}
}
}