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.cc68
1 files changed, 46 insertions, 22 deletions
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();