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.cc63
1 files changed, 62 insertions, 1 deletions
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc
index 70e6ac1..09bb5b7 100644
--- a/src/gpgpu-sim/scoreboard.cc
+++ b/src/gpgpu-sim/scoreboard.cc
@@ -43,6 +43,7 @@ Scoreboard::Scoreboard(unsigned sid, unsigned n_warps, class gpgpu_t* gpu,
longopregs.resize(n_warps);
sec_reg_table.resize(n_warps);
mask_reg_table.resize(n_warps);
+ slot_reg_table.resize(n_warps);
m_gpu = gpu;
@@ -127,6 +128,15 @@ void Scoreboard::reserveRegisters(const class warp_inst_t* inst) {
reserveRegisterMask(inst->warp_id(), inst->out[r], mask);
}
}
+ } else if (m_mode == 2) {
+ // Slot-pinned: insert into the inst's owning ibuffer half's table.
+ unsigned slot = inst->get_ibuffer_half_id();
+ assert(slot < NUM_SLOTS);
+ for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) {
+ if (inst->out[r] > 0) {
+ reserveRegisterSlot(inst->warp_id(), slot, inst->out[r]);
+ }
+ }
} else {
for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) {
if (inst->out[r] > 0) {
@@ -165,6 +175,15 @@ void Scoreboard::releaseRegisters(const class warp_inst_t* inst) {
longopregs[inst->warp_id()].erase(inst->out[r]);
}
}
+ } else if (m_mode == 2) {
+ unsigned slot = inst->get_ibuffer_half_id();
+ assert(slot < NUM_SLOTS);
+ for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) {
+ if (inst->out[r] > 0) {
+ releaseRegisterSlot(inst->warp_id(), slot, inst->out[r]);
+ longopregs[inst->warp_id()].erase(inst->out[r]);
+ }
+ }
} else {
for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) {
if (inst->out[r] > 0) {
@@ -210,6 +229,7 @@ bool Scoreboard::checkCollision(unsigned wid, const class inst_t* inst) const {
bool Scoreboard::pendingWrites(unsigned wid) const {
if (m_mode == 1) return !mask_reg_table[wid].empty();
+ if (m_mode == 2) return !bothSlotsClean(wid);
return !reg_table[wid].empty();
}
@@ -325,9 +345,11 @@ void Scoreboard::releaseRegisterMask(unsigned wid, unsigned reg,
void Scoreboard::releaseSetReg(unsigned wid, unsigned reg,
const active_mask_t &mask,
- bool is_intra_legacy) {
+ bool is_intra_legacy, unsigned slot_id) {
if (m_mode == 1) {
releaseRegisterMask(wid, reg, mask);
+ } else if (m_mode == 2) {
+ releaseRegisterSlot(wid, slot_id, reg);
} else if (is_intra_legacy) {
releaseRegisterSecondary(wid, reg);
} else {
@@ -335,6 +357,45 @@ void Scoreboard::releaseSetReg(unsigned wid, unsigned reg,
}
}
+// =====================================================================
+// Mode 2: slot-pinned scoreboards
+// =====================================================================
+
+void Scoreboard::reserveRegisterSlot(unsigned wid, unsigned slot,
+ unsigned regnum) {
+ assert(slot < NUM_SLOTS);
+ // Idempotent insert: same slot may try to reserve same reg if a
+ // back-to-back write to the same dest is co-issued by the same split
+ // through this slot. Mode 2 keeps it as a flat set (not ref-counted)
+ // for simplicity — relies on writeback's idempotent erase semantics.
+ slot_reg_table[wid][slot].insert(regnum);
+}
+
+void Scoreboard::releaseRegisterSlot(unsigned wid, unsigned slot,
+ unsigned regnum) {
+ assert(slot < NUM_SLOTS);
+ slot_reg_table[wid][slot].erase(regnum);
+}
+
+bool Scoreboard::checkCollisionSlot(unsigned wid, unsigned slot,
+ const class inst_t *inst) const {
+ assert(slot < NUM_SLOTS);
+ std::set<int> inst_regs;
+ for (unsigned i = 0; i < inst->outcount; i++) inst_regs.insert(inst->out[i]);
+ for (unsigned j = 0; j < inst->incount; j++) inst_regs.insert(inst->in[j]);
+ if (inst->pred > 0) inst_regs.insert(inst->pred);
+ if (inst->ar1 > 0) inst_regs.insert(inst->ar1);
+ if (inst->ar2 > 0) inst_regs.insert(inst->ar2);
+ for (auto reg : inst_regs) {
+ if (reg <= 0) continue;
+ if (slot_reg_table[wid][slot].find((unsigned)reg) !=
+ slot_reg_table[wid][slot].end()) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool Scoreboard::checkCollisionMask(unsigned wid, const class inst_t *inst,
const active_mask_t &mask) const {
std::set<int> inst_regs;