summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpgpu-sim/shader.cc188
-rw-r--r--src/gpgpu-sim/shader.h51
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() {}