diff options
| author | Tor Aamodt <[email protected]> | 2010-08-29 14:55:25 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-08-29 14:55:25 -0800 |
| commit | 80e1b49ff823190d0316623d414a343575c93eae (patch) | |
| tree | 273e041128687af72e31161cce5759f6819aef97 /src/gpgpu-sim/scoreboard.cc | |
| parent | 5cb919d7fbe3e5b388b9c83b22762dad96da56b1 (diff) | |
- integrate changes from fermi-test (CL's under that path in range 7261-7418).
(add scoreboard logic from ptxplus branch and modified operand collector
with parallel ALU/SFU pipelines)
passing regressions
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7419]
Diffstat (limited to 'src/gpgpu-sim/scoreboard.cc')
| -rw-r--r-- | src/gpgpu-sim/scoreboard.cc | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc new file mode 100644 index 0000000..4ebcee9 --- /dev/null +++ b/src/gpgpu-sim/scoreboard.cc @@ -0,0 +1,129 @@ +/* + * scoreboard.cc + * + * Created on: Aug 10, 2010 + * Author: inder + */ + +#include "scoreboard.h" +#include "shader.h" +#include "../cuda-sim/ptx_sim.h" + + +//Constructor +Scoreboard::Scoreboard( int sid, int n_warps ) +{ + this->sid = sid; + //Initialize size of table + reg_table.resize(n_warps); +} + +// Print scoreboard contents +void Scoreboard::printContents() { + printf("scoreboard contents (sid=%d): \n", sid); + for(unsigned i=0; i<reg_table.size(); i++) { + if(reg_table[i].size() == 0 ) continue; + printf(" wid = %d: ", i); + std::set<int>::iterator it; + for ( it=reg_table[i].begin() ; it != reg_table[i].end(); it++ ) + printf("%d ", *it); + printf("\n"); + } +} + + +// Mark register as write-pending +void Scoreboard::reserveRegister(int wid, int regnum) { + //printf("Reserving register sid=%d wid=%d regnum=%d\n", sid, wid, regnum); + + if( !(reg_table[wid].find(regnum) == reg_table[wid].end()) ){ + printf("Error: trying to reserve an already reserved register (sid=%d, wid=%d, regnum=%d).", sid, wid, regnum); + assert(reg_table[wid].find(regnum) == reg_table[wid].end()); + } + + reg_table[wid].insert(regnum); +} + + +// Unmark register as write-pending +void Scoreboard::releaseRegister(int wid, int regnum) { + //printf("Releasing register sid=%d wid=%d regnum=%d\n", sid, wid, regnum); + + if( !(reg_table[wid].find(regnum) != reg_table[wid].end()) ) { + printf("Error: trying to release an unreserved register (sid=%d, wid=%d, regnum=%d).", sid, wid, regnum); + assert(reg_table[wid].find(regnum) != reg_table[wid].end()); + } + + reg_table[wid].erase(regnum); +} + + +// Reserve registers for an instruction +void Scoreboard::reserveRegisters(int wid, void* inst_void) { + inst_t *inst = (inst_t *) inst_void; + + // Reserve registers + if(inst->out[0] > 0) reserveRegister(wid, inst->out[0]); + if(inst->out[1] > 0) reserveRegister(wid, inst->out[1]); + if(inst->out[2] > 0) reserveRegister(wid, inst->out[2]); + if(inst->out[3] > 0) reserveRegister(wid, inst->out[3]); +} + +// Release registers for an instruction +void Scoreboard::releaseRegisters(int wid, void *inst_void) { + inst_t *inst = (inst_t *) inst_void; + + if(inst->out[0] > 0) releaseRegister(wid, inst->out[0]); + if(inst->out[1] > 0) releaseRegister(wid, inst->out[1]); + if(inst->out[2] > 0) releaseRegister(wid, inst->out[2]); + if(inst->out[3] > 0) releaseRegister(wid, inst->out[3]); +} + +// Checks to see if registers used by an instruction are reserved in the scoreboard +bool Scoreboard::checkCollision(int wid, void *inst_void) { + inst_t *inst = (inst_t *) inst_void; + + // Get list of all input and output registers + std::set<int> inst_regs; + + if(inst->out[0] > 0) inst_regs.insert(inst->out[0]); + if(inst->out[1] > 0) inst_regs.insert(inst->out[1]); + if(inst->out[2] > 0) inst_regs.insert(inst->out[2]); + if(inst->out[3] > 0) inst_regs.insert(inst->out[3]); + if(inst->in[0] > 0) inst_regs.insert(inst->in[0]); + if(inst->in[1] > 0) inst_regs.insert(inst->in[1]); + if(inst->in[2] > 0) inst_regs.insert(inst->in[2]); + if(inst->in[3] > 0) inst_regs.insert(inst->in[3]); + 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); + + /* + printf("Inst registers: "); + std::set<int>::iterator it; + for ( it=inst_regs.begin() ; it != inst_regs.end(); it++ ) + printf("%d ", *it); + printf("\n"); + */ + + // Check for collision, get the intersection of reserved registers and instruction registers + //std::set<int> reg_intr; + std::set<int>::iterator it2; + for ( it2=inst_regs.begin() ; it2 != inst_regs.end(); it2++ ) + if(reg_table[wid].find(*it2) != reg_table[wid].end()) { + //reg_intr.insert(*it2); + return true; + } + + return false; + + /* + printf("Intersection registers: "); + std::set<int>::iterator it3; + for ( it3=reg_intr.begin() ; it3 != reg_intr.end(); it3++ ) + printf("%d ", *it3); + printf("\n"); + */ + + +} |
