diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.cc | 21 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 72 |
2 files changed, 76 insertions, 17 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 1010d00..b164c73 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -181,6 +181,16 @@ void warp_inst_t::compute_simd_sets(unsigned num_sets, unsigned set_width) { info.set_active_mask.reset(); info.active_mask_in_warp.reset(); info.num_active_threads = 0; + // Pipeline-register warp_inst_t objects are reused, so the per-set + // coissuer-tracking fields can be stale from a prior issue. The LSU + // gates on (!valid || source_inst == NULL); without these resets a + // primary's set inherits a previous coissue's source_inst != NULL + // and split_id, causing m_pending_writes_secondary to be incremented + // on a key no future decrement targets → deadlock under sb1. + info.split_id = (unsigned)-1; + info.source_inst = NULL; + info.source_mask.reset(); + info.source_slot_id = (unsigned)-1; for (unsigned lane = 0; lane < set_width; lane++) { unsigned tid = s * set_width + lane; info.thread_ids[lane] = tid; @@ -208,6 +218,11 @@ void warp_inst_t::compute_simd_sets_compacted(unsigned num_sets, info.num_active_threads = 0; info.valid = false; info.source_inst = NULL; + // Clear remaining coissuer-tracking state stale from prior reuse. + // (source_inst=NULL alone defends LSU; reset the rest for symmetry.) + info.split_id = (unsigned)-1; + info.source_mask.reset(); + info.source_slot_id = (unsigned)-1; for (unsigned i = 0; i < MAX_WARP_SIZE; i++) info.thread_ids[i] = 0; } @@ -251,6 +266,12 @@ void warp_inst_t::compute_simd_sets_xor_static(unsigned num_sets, info.set_active_mask.reset(); info.active_mask_in_warp.reset(); info.num_active_threads = 0; + // See compute_simd_sets — clear coissuer-tracking state stale from + // prior issues on this reused pipeline-register slot. + info.split_id = (unsigned)-1; + info.source_inst = NULL; + info.source_mask.reset(); + info.source_slot_id = (unsigned)-1; } // xor_key = reverse of the low log2(warp_size) bits of m_warp_id diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index e9c2e19..a86393c 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -2477,8 +2477,18 @@ void scheduler_unit::try_utilization_max_coissue( continue; } unsigned sec_active = sec_mask_eff.count(); - unsigned sec_needed = (sec_active + set_width - 1) / set_width; - if (sec_needed > available_sets) { + // Use the same feasibility test as inter coissue. Under + // compaction != 2 partitions are fixed by thread_id, so the + // coissuer's set positions can overlap the composite's even + // when (active/set_width) <= available_sets. merge_simd_sets + // silently drops overlapping coissuer sets while the access + // was already injected, leaving m_pending_writes_secondary + // unincremented but later decremented at writeback (underflow + // on sb0/sb2, deadlock on sb1). + unsigned sec_needed = 0; + if (!check_coissue_feasibility(co_issue_composite, sec_inst, + sec_mask_eff, cand_warp_id, + available_sets, &sec_needed)) { m_stats->coissue_denied_by_no_sets[get_sid()]++; continue; } @@ -2517,16 +2527,14 @@ void scheduler_unit::try_utilization_max_coissue( it != pool.end() && available_sets > 0; it++) { coissue_cand_t &c = *it; // Re-check feasibility: prior picks may have filled sets that this - // candidate overlaps (only matters for compaction_mode != 2). + // candidate overlaps (only matters for compaction_mode != 2). Both + // intra and inter must re-evaluate against the *current* composite + // — the cached c.sets_needed from admission can be stale once an + // earlier pool entry has merged its sets in. unsigned needed = 0; - if (c.is_intra) { - if (c.sets_needed > available_sets) continue; - needed = c.sets_needed; - } else { - if (!check_coissue_feasibility(co_issue_composite, c.inst, c.mask, - c.warp_id, available_sets, &needed)) - continue; - } + if (!check_coissue_feasibility(co_issue_composite, c.inst, c.mask, + c.warp_id, available_sets, &needed)) + continue; if (c.is_intra) { if (m_shader->m_config->gpgpu_simd_partitioning_debug) { @@ -2798,8 +2806,18 @@ void scheduler_unit::try_utilization_max_coissue_window( continue; } unsigned sec_active = sec_mask_eff.count(); - unsigned sec_needed = (sec_active + set_width - 1) / set_width; - if (sec_needed > available_sets) { + // Use the same feasibility test as inter coissue. Under + // compaction != 2 partitions are fixed by thread_id, so the + // coissuer's set positions can overlap the composite's even + // when (active/set_width) <= available_sets. merge_simd_sets + // silently drops overlapping coissuer sets while the access + // was already injected, leaving m_pending_writes_secondary + // unincremented but later decremented at writeback (underflow + // on sb0/sb2, deadlock on sb1). + unsigned sec_needed = 0; + if (!check_coissue_feasibility(co_issue_composite, sec_inst, + sec_mask_eff, cand_warp_id, + available_sets, &sec_needed)) { m_stats->coissue_denied_by_no_sets[get_sid()]++; continue; } @@ -3120,8 +3138,18 @@ void scheduler_unit::try_utilization_max_coissue_window_centered( continue; } unsigned sec_active = sec_mask_eff.count(); - unsigned sec_needed = (sec_active + set_width - 1) / set_width; - if (sec_needed > available_sets) { + // Use the same feasibility test as inter coissue. Under + // compaction != 2 partitions are fixed by thread_id, so the + // coissuer's set positions can overlap the composite's even + // when (active/set_width) <= available_sets. merge_simd_sets + // silently drops overlapping coissuer sets while the access + // was already injected, leaving m_pending_writes_secondary + // unincremented but later decremented at writeback (underflow + // on sb0/sb2, deadlock on sb1). + unsigned sec_needed = 0; + if (!check_coissue_feasibility(co_issue_composite, sec_inst, + sec_mask_eff, cand_warp_id, + available_sets, &sec_needed)) { m_stats->coissue_denied_by_no_sets[get_sid()]++; continue; } @@ -3435,8 +3463,18 @@ void scheduler_unit::try_utilization_max_coissue_window_before( continue; } unsigned sec_active = sec_mask_eff.count(); - unsigned sec_needed = (sec_active + set_width - 1) / set_width; - if (sec_needed > available_sets) { + // Use the same feasibility test as inter coissue. Under + // compaction != 2 partitions are fixed by thread_id, so the + // coissuer's set positions can overlap the composite's even + // when (active/set_width) <= available_sets. merge_simd_sets + // silently drops overlapping coissuer sets while the access + // was already injected, leaving m_pending_writes_secondary + // unincremented but later decremented at writeback (underflow + // on sb0/sb2, deadlock on sb1). + unsigned sec_needed = 0; + if (!check_coissue_feasibility(co_issue_composite, sec_inst, + sec_mask_eff, cand_warp_id, + available_sets, &sec_needed)) { m_stats->coissue_denied_by_no_sets[get_sid()]++; continue; } |
