diff options
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 68 |
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(); |
