summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/scoreboard.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/scoreboard.cc')
-rw-r--r--src/gpgpu-sim/scoreboard.cc90
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);
+}