diff options
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 188 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 51 |
2 files changed, 185 insertions, 54 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index d433b6a..c874733 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -796,6 +796,40 @@ void shader_core_stats::print(FILE *fout) const { fprintf(fout, "%s%llu", b == 0 ? "" : ", ", tot_bin); } fprintf(fout, "]\n"); + + // Diagnostic counters (per-filter breakdown of inter-warp co-issue + // candidate rejections — quantifies the "silent" rejections that + // precede the coissue_denied_by_* counters). + unsigned long long tot_seen = 0, tot_null = 0, tot_done = 0, + tot_primary = 0, tot_picked = 0, + tot_iempty = 0, tot_waiting = 0, tot_simt = 0, + tot_noinst = 0, tot_pcm = 0, tot_spc0 = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + tot_seen += coissue_cand_seen[i]; + tot_null += coissue_skipped_null[i]; + tot_done += coissue_skipped_done_exit[i]; + tot_primary += coissue_skipped_is_primary[i]; + tot_picked += coissue_skipped_picked_earlier[i]; + tot_iempty += coissue_skipped_ibuffer_empty[i]; + tot_waiting += coissue_skipped_waiting[i]; + tot_simt += coissue_skipped_simt_blocked[i]; + tot_noinst += coissue_skipped_no_inst[i]; + tot_pcm += coissue_skipped_pc_mismatch[i]; + tot_spc0 += coissue_skipped_samepc_pass0[i]; + } + fprintf(fout, "gpu_tot_coissue_cand_seen = %llu\n", tot_seen); + fprintf(fout, "gpu_tot_coissue_skipped_null = %llu\n", tot_null); + fprintf(fout, "gpu_tot_coissue_skipped_done_exit = %llu\n", tot_done); + fprintf(fout, "gpu_tot_coissue_skipped_is_primary = %llu\n", tot_primary); + fprintf(fout, "gpu_tot_coissue_skipped_picked_earlier = %llu\n", + tot_picked); + fprintf(fout, "gpu_tot_coissue_skipped_ibuffer_empty = %llu\n", + tot_iempty); + fprintf(fout, "gpu_tot_coissue_skipped_waiting = %llu\n", tot_waiting); + fprintf(fout, "gpu_tot_coissue_skipped_simt_blocked = %llu\n", tot_simt); + fprintf(fout, "gpu_tot_coissue_skipped_no_inst = %llu\n", tot_noinst); + fprintf(fout, "gpu_tot_coissue_skipped_pc_mismatch = %llu\n", tot_pcm); + fprintf(fout, "gpu_tot_coissue_skipped_samepc_pass0 = %llu\n", tot_spc0); } } @@ -1686,16 +1720,38 @@ void scheduler_unit::try_inter_warp_coissue( for (unsigned pass = 0; pass < num_passes && available_sets > 0; pass++) { for (std::vector<shd_warp_t *>::iterator iter2 = cand_warps.begin(); iter2 != cand_warps.end() && available_sets > 0; iter2++) { - if ((*iter2) == NULL || (*iter2)->done_exit()) continue; + // Count every candidate-warp iteration as "seen" so per-filter + // skip counts are interpretable as a fraction. + m_stats->coissue_cand_seen[get_sid()]++; + if ((*iter2) == NULL) { + m_stats->coissue_skipped_null[get_sid()]++; + continue; + } + if ((*iter2)->done_exit()) { + m_stats->coissue_skipped_done_exit[get_sid()]++; + continue; + } unsigned cand_warp_id = (*iter2)->get_warp_id(); // Skip the primary warp (already issued). - if (cand_warp_id == co_issue_primary_warp_id) continue; - if (picked_warps.count(cand_warp_id)) continue; + if (cand_warp_id == co_issue_primary_warp_id) { + m_stats->coissue_skipped_is_primary[get_sid()]++; + continue; + } + if (picked_warps.count(cand_warp_id)) { + m_stats->coissue_skipped_picked_earlier[get_sid()]++; + continue; + } // Basic eligibility. - if (warp(cand_warp_id).ibuffer_empty()) continue; - if (warp(cand_warp_id).waiting()) continue; + if (warp(cand_warp_id).ibuffer_empty()) { + m_stats->coissue_skipped_ibuffer_empty[get_sid()]++; + continue; + } + if (warp(cand_warp_id).waiting()) { + m_stats->coissue_skipped_waiting[get_sid()]++; + continue; + } // AWARE reconvergence eligibility. bool simt_ok = true; @@ -1705,17 +1761,29 @@ void scheduler_unit::try_inter_warp_coissue( !warp(cand_warp_id).pending_reconvergence() && !warp(cand_warp_id).virtualized(); } - if (!simt_ok) continue; + if (!simt_ok) { + m_stats->coissue_skipped_simt_blocked[get_sid()]++; + continue; + } const warp_inst_t *cand_inst = warp(cand_warp_id).ibuffer_next_inst(); - if (!cand_inst) continue; - if (!warp(cand_warp_id).ibuffer_next_valid()) continue; + if (!cand_inst) { + m_stats->coissue_skipped_no_inst[get_sid()]++; + continue; + } + if (!warp(cand_warp_id).ibuffer_next_valid()) { + m_stats->coissue_skipped_no_inst[get_sid()]++; + continue; + } // Control hazard check. unsigned cand_pc, cand_rpc; m_shader->get_pdom_stack_top_info(cand_warp_id, cand_inst, &cand_pc, &cand_rpc); - if (cand_pc != cand_inst->pc) continue; + if (cand_pc != cand_inst->pc) { + m_stats->coissue_skipped_pc_mismatch[get_sid()]++; + continue; + } // Scoreboard check. if (m_scoreboard->checkCollision(cand_warp_id, cand_inst)) { @@ -1730,11 +1798,10 @@ void scheduler_unit::try_inter_warp_coissue( } // same-PC mode: pass 0 requires pc==primary_pc; pass 1 takes any. - if (sort_mode == 2 && pass == 0 && cand_inst->pc != primary_pc) + if (sort_mode == 2 && pass == 0 && cand_inst->pc != primary_pc) { + m_stats->coissue_skipped_samepc_pass0[get_sid()]++; continue; - // Don't re-issue the same warp in pass 1 (it would already have - // been picked in pass 0 if it qualified; but ibuffer_next_inst - // has advanced for picks from pass 0, so this is self-consistent). + } const active_mask_t &cand_mask = m_shader->get_active_mask(cand_warp_id, cand_inst); @@ -1931,51 +1998,64 @@ void scheduler_unit::try_utilization_max_coissue( pool.push_back(c); } - // --- Intra-warp candidates (primary's secondary slots 2..3) --- + // --- Intra-warp candidates (all warps' secondary slots 2..3) --- if (m_shader->m_config->model == AWARE_RECONVERGENCE) { - const unsigned primary_warp_id = co_issue_primary_warp_id; - for (unsigned sec_slot = 2; sec_slot < 4; sec_slot++) { - if (!warp(primary_warp_id).ibuffer_slot_valid(sec_slot)) continue; - const warp_inst_t *sec_inst = - warp(primary_warp_id).ibuffer_slot_inst(sec_slot); - if (!sec_inst) continue; - unsigned sec_split_id = - warp(primary_warp_id).ibuffer_slot_split_id(sec_slot); - const active_mask_t &sec_mask = - warp(primary_warp_id).ibuffer_slot_split_mask(sec_slot); + for (std::vector<shd_warp_t *>::const_iterator iter = + m_next_cycle_prioritized_warps.begin(); + iter != m_next_cycle_prioritized_warps.end(); iter++) { + if ((*iter) == NULL || (*iter)->done_exit()) continue; + unsigned cand_warp_id = (*iter)->get_warp_id(); + if (warp(cand_warp_id).waiting()) continue; - if (!m_shader->is_split_valid(primary_warp_id, sec_split_id)) continue; - unsigned split_pc; - simt_mask_t split_mask; - m_shader->get_split_info(primary_warp_id, sec_split_id, &split_pc, - &split_mask); - if (split_pc != sec_inst->pc) continue; - if (classify_fu_type(sec_inst) != co_issue_fu_type) { - m_stats->coissue_denied_by_fu_mismatch[get_sid()]++; - continue; - } - if (m_scoreboard->checkCollisionSecondary(primary_warp_id, sec_inst)) { - m_stats->coissue_denied_by_scoreboard[get_sid()]++; - continue; - } + bool simt_ok = warp(cand_warp_id).valid() && + !warp(cand_warp_id).blocked() && + !warp(cand_warp_id).pending_reconvergence() && + !warp(cand_warp_id).virtualized(); + if (!simt_ok) continue; - unsigned sec_active = sec_mask.count(); - unsigned sec_needed = (sec_active + set_width - 1) / set_width; - if (sec_needed > available_sets) { - m_stats->coissue_denied_by_no_sets[get_sid()]++; - continue; - } + for (unsigned sec_slot = 2; sec_slot < 4; sec_slot++) { + if (!warp(cand_warp_id).ibuffer_slot_valid(sec_slot)) continue; + const warp_inst_t *sec_inst = + warp(cand_warp_id).ibuffer_slot_inst(sec_slot); + if (!sec_inst) continue; + unsigned sec_split_id = + warp(cand_warp_id).ibuffer_slot_split_id(sec_slot); + const active_mask_t &sec_mask = + warp(cand_warp_id).ibuffer_slot_split_mask(sec_slot); + + if (!m_shader->is_split_valid(cand_warp_id, sec_split_id)) continue; + unsigned split_pc; + simt_mask_t split_mask; + m_shader->get_split_info(cand_warp_id, sec_split_id, &split_pc, + &split_mask); + if (split_pc != sec_inst->pc) continue; + if (classify_fu_type(sec_inst) != co_issue_fu_type) { + m_stats->coissue_denied_by_fu_mismatch[get_sid()]++; + continue; + } + if (m_scoreboard->checkCollisionSecondary(cand_warp_id, sec_inst)) { + m_stats->coissue_denied_by_scoreboard[get_sid()]++; + continue; + } - coissue_cand_t c; - c.is_intra = true; - c.warp_id = primary_warp_id; - c.split_id = sec_split_id; - c.inst = sec_inst; - c.mask = sec_mask; - c.sec_slot = sec_slot; - c.active_count = sec_active; - c.sets_needed = sec_needed; - pool.push_back(c); + unsigned sec_active = sec_mask.count(); + unsigned sec_needed = (sec_active + set_width - 1) / set_width; + if (sec_needed > available_sets) { + m_stats->coissue_denied_by_no_sets[get_sid()]++; + continue; + } + + coissue_cand_t c; + c.is_intra = true; + c.warp_id = cand_warp_id; + c.split_id = sec_split_id; + c.inst = sec_inst; + c.mask = sec_mask; + c.sec_slot = sec_slot; + c.active_count = sec_active; + c.sets_needed = sec_needed; + pool.push_back(c); + } } } diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 42d807c..2800b81 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -2096,6 +2096,22 @@ struct shader_core_stats_pod { unsigned long long *coissue_total_active_lanes; unsigned long long *coissue_composite_cycles; unsigned long long *simd_sets_used_histogram; + + // --- Temporary diagnostic counters for inter-warp candidate filters --- + // These quantify the "silent" rejections before the existing + // coissue_denied_by_* counters. Used to diagnose why inter-warp + // co-issue never fires on stall-bound workloads like `nw` and `lud`. + unsigned long long *coissue_cand_seen; + unsigned long long *coissue_skipped_null; + unsigned long long *coissue_skipped_done_exit; + unsigned long long *coissue_skipped_is_primary; + unsigned long long *coissue_skipped_picked_earlier; + unsigned long long *coissue_skipped_ibuffer_empty; + unsigned long long *coissue_skipped_waiting; + unsigned long long *coissue_skipped_simt_blocked; + unsigned long long *coissue_skipped_no_inst; + unsigned long long *coissue_skipped_pc_mismatch; + unsigned long long *coissue_skipped_samepc_pass0; }; class shader_core_stats : public shader_core_stats_pod { @@ -2229,6 +2245,30 @@ class shader_core_stats : public shader_core_stats_pod { unsigned nbins = config->gpgpu_num_simd_sets + 1; simd_sets_used_histogram = (unsigned long long *)calloc( (size_t)config->num_shader() * nbins, sizeof(unsigned long long)); + + // Diagnostic counters + coissue_cand_seen = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_null = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_done_exit = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_is_primary = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_picked_earlier = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_ibuffer_empty = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_waiting = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_simt_blocked = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_no_inst = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_pc_mismatch = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); + coissue_skipped_samepc_pass0 = (unsigned long long *)calloc( + config->num_shader(), sizeof(unsigned long long)); } ~shader_core_stats() { @@ -2290,6 +2330,17 @@ class shader_core_stats : public shader_core_stats_pod { free(coissue_total_active_lanes); free(coissue_composite_cycles); free(simd_sets_used_histogram); + free(coissue_cand_seen); + free(coissue_skipped_null); + free(coissue_skipped_done_exit); + free(coissue_skipped_is_primary); + free(coissue_skipped_picked_earlier); + free(coissue_skipped_ibuffer_empty); + free(coissue_skipped_waiting); + free(coissue_skipped_simt_blocked); + free(coissue_skipped_no_inst); + free(coissue_skipped_pc_mismatch); + free(coissue_skipped_samepc_pass0); } void new_grid() {} |
