From 150e3a9c218fa1c99cd2391885ebd7e1c86a9430 Mon Sep 17 00:00:00 2001 From: Davit Grigoryan Date: Fri, 24 Apr 2026 19:46:19 +0000 Subject: impl mixed-space mem instruction co-issuing --- src/abstract_hardware_model.h | 105 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 1e3c94e..1a42657 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1119,6 +1119,20 @@ enum divergence_support_t { const unsigned MAX_ACCESSES_PER_INSN_PER_THREAD = 8; +// Mixed-space MEM co-issue (v2): per-lane address storage for a shared- +// memory coissuer set. Captured at co_issue_warp time BEFORE temp_inst +// dies, so later per-set bank conflict recomputes can run against each +// set's own per-lane addresses without colliding on the composite's +// m_per_scalar_thread (which is keyed by thread-in-warp and would be +// overwritten across inter-warp coissuers). +struct simd_set_addr_entry { + new_addr_type memreqaddr[MAX_ACCESSES_PER_INSN_PER_THREAD]; + simd_set_addr_entry() { + for (unsigned i = 0; i < MAX_ACCESSES_PER_INSN_PER_THREAD; i++) + memreqaddr[i] = 0; + } +}; + // SIMD lane partitioning: per-set execution data struct simd_set_info { unsigned set_id; // Set index (0 to num_sets-1) @@ -1131,13 +1145,29 @@ struct simd_set_info { bool valid; // Whether this set has any active threads const inst_t *source_inst; // Pointer to static decoded instruction (for MIMD) + // Mixed-space MEM co-issue (v2): per-set shared state. + // Populated only when source_inst's space is shared/sstarr; otherwise + // unused. `cycles` is the set's bank-conflict depth (modelled per-set + // in shared_cycle). `per_thread_addrs` is the captured per-lane + // memreqaddr for this set. + unsigned cycles; + std::vector per_thread_addrs; + simd_set_info() : set_id(0), warp_id(0), split_id((unsigned)-1), - num_active_threads(0), valid(false), source_inst(NULL) { + num_active_threads(0), valid(false), source_inst(NULL), cycles(0) { set_active_mask.reset(); active_mask_in_warp.reset(); for (unsigned i = 0; i < MAX_WARP_SIZE; i++) thread_ids[i] = 0; } + + // Mirror of warp_inst_t::has_dispatch_delay / dispatch_delay, but + // per-set. Used by the per-set shared_cycle path in ldst_unit. + bool has_dispatch_delay() const { return cycles > 0; } + bool dispatch_delay() { + if (cycles > 0) cycles--; + return cycles > 0; + } }; class warp_inst_t : public inst_t { @@ -1205,8 +1235,68 @@ class warp_inst_t : public inst_t { const std::vector &get_simd_sets() const { return m_simd_sets; } + // Mixed-space MEM co-issue (v2): mutable accessor for capture path. + std::vector &get_simd_sets_mutable() { return m_simd_sets; } unsigned num_active_simd_sets() const; + + // Mixed-space MEM co-issue (v2): space-bucket classification. "shared + // bucket" = shared_space/sstarr_space; "global bucket" = + // global/local/param_local. + static bool is_shared_bucket_space(enum _memory_space_t t) { + return t == shared_space || t == sstarr_space; + } + static bool is_global_bucket_space(enum _memory_space_t t) { + return t == global_space || t == local_space || t == param_space_local; + } + // A composite has a shared/global "subcomposite" if any valid simd_set + // (including the primary set when source_inst==NULL) has a source space + // in that bucket. Primary set's space is the composite's own `space`. + bool has_shared_subcomposite() const { + for (unsigned s = 0; s < m_simd_sets.size(); s++) { + if (!m_simd_sets[s].valid) continue; + enum _memory_space_t sp = (m_simd_sets[s].source_inst == NULL) + ? space.get_type() + : m_simd_sets[s].source_inst->space.get_type(); + if (is_shared_bucket_space(sp)) return true; + } + return false; + } + bool has_global_subcomposite() const { + for (unsigned s = 0; s < m_simd_sets.size(); s++) { + if (!m_simd_sets[s].valid) continue; + enum _memory_space_t sp = (m_simd_sets[s].source_inst == NULL) + ? space.get_type() + : m_simd_sets[s].source_inst->space.get_type(); + if (is_global_bucket_space(sp)) return true; + } + return false; + } + bool is_mixed_space_composite() const { + return has_shared_subcomposite() && has_global_subcomposite(); + } bool has_simd_sets() const { return !m_simd_sets.empty(); } + + // Mixed-space MEM co-issue (v2): copy this instruction's per-lane + // memreqaddr entries into `set.per_thread_addrs`, and copy this + // instruction's bank-conflict `cycles` into `set.cycles`. Used by + // co_issue_warp for SHARED coissuer sets BEFORE temp_inst dies, so + // later per-set bank-conflict re-checks can read each set's own + // addresses without colliding on the composite's m_per_scalar_thread. + void capture_per_set_shared_state(simd_set_info &set, + unsigned set_width) const { + set.cycles = cycles; + if (!m_per_scalar_thread_valid) return; + set.per_thread_addrs.assign(set_width, simd_set_addr_entry()); + for (unsigned lane = 0; lane < set_width; lane++) { + if (!set.set_active_mask.test(lane)) continue; + unsigned t = set.thread_ids[lane]; + if (t >= m_per_scalar_thread.size()) continue; + for (unsigned i = 0; i < MAX_ACCESSES_PER_INSN_PER_THREAD; i++) { + set.per_thread_addrs[lane].memreqaddr[i] = + m_per_scalar_thread[t].memreqaddr[i]; + } + } + } void merge_simd_sets(const std::vector &other_sets); void set_source_inst_on_sets(const inst_t *src); void set_split_id_on_sets(unsigned split_id); @@ -1408,6 +1498,19 @@ class warp_inst_t : public inst_t { bool m_is_depbar; unsigned int m_depbar_group_no; + + // Mixed-space MEM co-issue (Option A / Stage 6): tracks whether the + // shared-source scoreboards of this MIXED composite have already been + // released via the early-release path in ldst_unit::cycle. Set once; + // checked by both the early-release path (to avoid re-release as + // shared_cycle keeps returning true) and by the final mixed-retire + // (to avoid double-releasing shared sources at dispatch_reg clear). + // Default false. Only meaningful for mixed composites. + public: + bool shared_side_released() const { return m_shared_side_released; } + void set_shared_side_released(bool v) { m_shared_side_released = v; } + private: + bool m_shared_side_released = false; }; void move_warp(warp_inst_t *&dst, warp_inst_t *&src); -- cgit v1.3