summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorDavit Grigoryan <[email protected]>2026-04-12 01:05:57 +0000
committerDavit Grigoryan <[email protected]>2026-04-12 01:05:57 +0000
commitc3c124bfdf4384db3b6e852b517dc8828577a3a5 (patch)
tree4dca37ffc13bf3939d9b051898fb131a22c44729 /src/gpgpu-sim
parent29d90a95ffa4287f58dc30a2e3488edf13d6c143 (diff)
impl thread compaction
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-sim.cc4
-rw-r--r--src/gpgpu-sim/shader.cc68
-rw-r--r--src/gpgpu-sim/shader.h3
3 files changed, 52 insertions, 23 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 17c7247..7b186aa 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -681,6 +681,10 @@ void shader_core_config::reg_options(class OptionParser *opp) {
option_parser_register(
opp, "-gpgpu_num_simd_sets", OPT_UINT32, &gpgpu_num_simd_sets,
"Number of SIMD sets to partition lanes into (default = 1)", "1");
+ option_parser_register(
+ opp, "-gpgpu_enable_compaction", OPT_BOOL, &gpgpu_enable_compaction,
+ "Enable thread compaction into fewer SIMD sets (default = disabled)",
+ "0");
for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) {
std::stringstream ss;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index ea2d9b3..b0b1371 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -1105,8 +1105,12 @@ 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) {
- (*pipe_reg)->compute_simd_sets(m_config->gpgpu_num_simd_sets,
- m_config->simd_set_width);
+ 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);
}
func_exec_inst(**pipe_reg);
@@ -1209,7 +1213,8 @@ warp_inst_t *shader_core_ctx::issue_warp(register_set &pipe_reg_set,
void shader_core_ctx::co_issue_warp(warp_inst_t *composite,
const warp_inst_t *next_inst,
const active_mask_t &active_mask,
- unsigned warp_id, unsigned sch_id) {
+ unsigned warp_id, unsigned sch_id,
+ unsigned start_set) {
// Free the co-issued warp's I-buffer entry
m_warp[warp_id]->ibuffer_free();
assert(next_inst->valid());
@@ -1222,8 +1227,12 @@ 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
- temp_inst.compute_simd_sets(m_config->gpgpu_num_simd_sets,
- m_config->simd_set_width);
+ 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);
// Functional execution for the co-issued warp's threads
func_exec_inst(temp_inst);
@@ -1718,12 +1727,16 @@ void scheduler_unit::cycle() {
if (m_shader->m_config->gpgpu_simd_partitioning && co_issue_composite != NULL &&
co_issue_fu_type != exec_unit_type_t::MEM &&
co_issue_fu_type != exec_unit_type_t::NONE) {
- // Count available (unused) sets in the composite
+ // Count available (unused) sets and find next free set
unsigned available_sets = 0;
+ unsigned next_free_set = 0;
const std::vector<simd_set_info> &primary_sets =
co_issue_composite->get_simd_sets();
for (unsigned s = 0; s < primary_sets.size(); s++) {
- if (!primary_sets[s].valid) available_sets++;
+ if (!primary_sets[s].valid)
+ available_sets++;
+ else
+ next_free_set = s + 1; // track end of used sets (for compaction)
}
if (available_sets > 0) {
@@ -1733,6 +1746,8 @@ void scheduler_unit::cycle() {
m_shader->get_gpu()->gpu_tot_sim_cycle,
get_sid(), m_id, available_sets, co_issue_primary_warp_id);
+ unsigned set_width = m_shader->m_config->simd_set_width;
+
// Scan other warps for co-issue candidates
for (std::vector<shd_warp_t *>::const_iterator iter2 =
m_next_cycle_prioritized_warps.begin();
@@ -1802,26 +1817,34 @@ void scheduler_unit::cycle() {
}
if (cand_fu_type != co_issue_fu_type) continue;
- // Get candidate's active mask and compute its SIMD sets
+ // Get candidate's active mask
const active_mask_t &cand_mask =
m_shader->get_active_mask(cand_warp_id, cand_inst);
- // Build candidate's SIMD set info to check for overlap
- 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);
+ unsigned cand_sets_needed;
+ bool can_co_issue;
- // Check set overlap with the current composite
- if (warp_inst_t::simd_sets_overlap(co_issue_composite->get_simd_sets(),
- cand_temp.get_simd_sets())) {
- continue; // sets conflict, can't co-issue
+ if (m_shader->m_config->gpgpu_enable_compaction) {
+ // With compaction: just count sets needed, no overlap check
+ 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
+ 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);
+ can_co_issue =
+ !warp_inst_t::simd_sets_overlap(
+ co_issue_composite->get_simd_sets(),
+ cand_temp.get_simd_sets());
+ cand_sets_needed = cand_temp.num_active_simd_sets();
+ if (cand_sets_needed > available_sets) can_co_issue = false;
}
- // Count candidate's sets to verify they fit
- unsigned cand_sets_needed = cand_temp.num_active_simd_sets();
- if (cand_sets_needed > available_sets) continue;
+ if (!can_co_issue) continue;
printf("SIMD_SETS: cycle %llu, core %u, sched %u: warp %u "
"CO-ISSUED with primary warp %u (%u sets)\n",
@@ -1832,9 +1855,10 @@ void scheduler_unit::cycle() {
// Co-issue: functional execution, SIMT update, scoreboard, merge
m_shader->co_issue_warp(co_issue_composite, cand_inst, cand_mask,
- cand_warp_id, m_id);
+ cand_warp_id, m_id, next_free_set);
available_sets -= cand_sets_needed;
+ next_free_set += cand_sets_needed;
// Advance candidate warp's ibuffer
warp(cand_warp_id).ibuffer_step();
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index c01abf1..31008ec 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1766,6 +1766,7 @@ class shader_core_config : public core_config {
bool gpgpu_simd_partitioning;
unsigned gpgpu_num_simd_sets;
unsigned simd_set_width; // derived: warp_size / num_simd_sets
+ bool gpgpu_enable_compaction;
unsigned n_simt_cores_per_cluster;
unsigned n_simt_clusters;
@@ -2537,7 +2538,7 @@ class shader_core_ctx : public core_t {
unsigned warp_id, unsigned sch_id);
void co_issue_warp(warp_inst_t *composite, const warp_inst_t *next_inst,
const active_mask_t &active_mask, unsigned warp_id,
- unsigned sch_id);
+ unsigned sch_id, unsigned start_set = 0);
void create_front_pipeline();
void create_schedulers();