diff options
| author | Davit Grigoryan <[email protected]> | 2026-04-27 02:10:06 +0000 |
|---|---|---|
| committer | Davit Grigoryan <[email protected]> | 2026-04-27 02:10:06 +0000 |
| commit | 2f190971f5f952f55197d385c688667439bc6649 (patch) | |
| tree | 5f9945497f9ac36ee1cbb35d6aca1dea39e6a08b /src/gpgpu-sim/scoreboard.cc | |
| parent | 13d5fae1ac28988d071b4459af169e53361921d8 (diff) | |
add debug scoreboard stats counting
Diffstat (limited to 'src/gpgpu-sim/scoreboard.cc')
| -rw-r--r-- | src/gpgpu-sim/scoreboard.cc | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc index de71807..bcaea56 100644 --- a/src/gpgpu-sim/scoreboard.cc +++ b/src/gpgpu-sim/scoreboard.cc @@ -28,6 +28,7 @@ #include "scoreboard.h" #include "../cuda-sim/ptx_sim.h" +#include "gpu-sim.h" #include "shader.h" #include "shader_trace.h" @@ -41,6 +42,19 @@ Scoreboard::Scoreboard(unsigned sid, unsigned n_warps, class gpgpu_t* gpu) sec_reg_table.resize(n_warps); m_gpu = gpu; + + m_primary_reserve_calls = 0; + m_primary_release_calls = 0; + m_sec_reserve_calls = 0; + m_sec_release_calls = 0; + m_sec_clear_calls = 0; + m_sec_clear_regs_dropped = 0; + m_primary_total_duration_cycles = 0; + m_primary_completed_reservations = 0; + m_primary_max_duration_cycles = 0; + m_sec_total_duration_cycles = 0; + m_sec_completed_reservations = 0; + m_sec_max_duration_cycles = 0; } // Print scoreboard contents @@ -67,6 +81,9 @@ void Scoreboard::reserveRegister(unsigned wid, unsigned regnum) { SHADER_DPRINTF(SCOREBOARD, "Reserved Register - warp:%d, reg: %d\n", wid, regnum); reg_table[wid].insert(regnum); + m_primary_reserve_calls++; + m_primary_resv_cycle[std::make_pair(wid, regnum)] = + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle; } // Unmark register as write-pending @@ -75,6 +92,18 @@ void Scoreboard::releaseRegister(unsigned wid, unsigned regnum) { SHADER_DPRINTF(SCOREBOARD, "Release register - warp:%d, reg: %d\n", wid, regnum); reg_table[wid].erase(regnum); + m_primary_release_calls++; + auto key = std::make_pair(wid, regnum); + auto it = m_primary_resv_cycle.find(key); + if (it != m_primary_resv_cycle.end()) { + unsigned long long now = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle; + unsigned long long dur = now - it->second; + m_primary_total_duration_cycles += dur; + m_primary_completed_reservations++; + if (dur > m_primary_max_duration_cycles) + m_primary_max_duration_cycles = dur; + m_primary_resv_cycle.erase(it); + } } const bool Scoreboard::islongop(unsigned warp_id, unsigned regnum) { @@ -158,11 +187,28 @@ bool Scoreboard::pendingWrites(unsigned wid) const { void Scoreboard::reserveRegisterSecondary(unsigned wid, unsigned regnum) { // No abort on duplicate — secondary may share register names with primary - sec_reg_table[wid].insert(regnum); + bool inserted = sec_reg_table[wid].insert(regnum).second; + if (inserted) { + m_sec_reserve_calls++; + m_sec_resv_cycle[std::make_pair(wid, regnum)] = + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle; + } } void Scoreboard::releaseRegisterSecondary(unsigned wid, unsigned regnum) { - sec_reg_table[wid].erase(regnum); + size_t n = sec_reg_table[wid].erase(regnum); + if (n == 0) return; + m_sec_release_calls++; + auto key = std::make_pair(wid, regnum); + auto it = m_sec_resv_cycle.find(key); + if (it != m_sec_resv_cycle.end()) { + unsigned long long now = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle; + unsigned long long dur = now - it->second; + m_sec_total_duration_cycles += dur; + m_sec_completed_reservations++; + if (dur > m_sec_max_duration_cycles) m_sec_max_duration_cycles = dur; + m_sec_resv_cycle.erase(it); + } } bool Scoreboard::checkCollisionSecondary(unsigned wid, @@ -181,5 +227,45 @@ bool Scoreboard::checkCollisionSecondary(unsigned wid, } void Scoreboard::clearSecondary(unsigned wid) { + m_sec_clear_calls++; + m_sec_clear_regs_dropped += sec_reg_table[wid].size(); + // Drop in-flight duration timestamps for any regs we are dropping — + // these are abandoned reservations (e.g. warp completed, pipeline flush) + // and counting their duration would skew the histogram. + for (auto reg : sec_reg_table[wid]) + m_sec_resv_cycle.erase(std::make_pair(wid, reg)); sec_reg_table[wid].clear(); } + +// End-of-run accounting dump. +void Scoreboard::dumpAccounting(FILE* out) const { + unsigned long long primary_remaining = 0; + unsigned long long sec_remaining = 0; + for (unsigned w = 0; w < reg_table.size(); w++) + primary_remaining += reg_table[w].size(); + for (unsigned w = 0; w < sec_reg_table.size(); w++) + sec_remaining += sec_reg_table[w].size(); + double primary_avg_dur = + m_primary_completed_reservations + ? (double)m_primary_total_duration_cycles / + (double)m_primary_completed_reservations + : 0.0; + double sec_avg_dur = + m_sec_completed_reservations + ? (double)m_sec_total_duration_cycles / + (double)m_sec_completed_reservations + : 0.0; + fprintf(out, + "scoreboard_accounting sid=%u " + "primary: reserves=%llu releases=%llu remaining=%llu " + "completed=%llu avg_cycles=%.2f max_cycles=%llu " + "| secondary: reserves=%llu releases=%llu remaining=%llu " + "completed=%llu avg_cycles=%.2f max_cycles=%llu " + "clearSecondary=%llu regs_dropped_by_clear=%llu\n", + m_sid, m_primary_reserve_calls, m_primary_release_calls, + primary_remaining, m_primary_completed_reservations, primary_avg_dur, + m_primary_max_duration_cycles, m_sec_reserve_calls, + m_sec_release_calls, sec_remaining, m_sec_completed_reservations, + sec_avg_dur, m_sec_max_duration_cycles, m_sec_clear_calls, + m_sec_clear_regs_dropped); +} |
