summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/shader.h')
-rw-r--r--src/gpgpu-sim/shader.h129
1 files changed, 118 insertions, 11 deletions
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 31008ec..d8103ac 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -223,27 +223,102 @@ class shd_warp_t {
assert(slot < IBUFFER_SIZE);
m_ibuffer[slot].m_inst = pI;
m_ibuffer[slot].m_valid = true;
- m_next = 0;
+ m_ibuffer[slot].m_split_id = (unsigned)-1;
+ m_ibuffer[slot].m_split_mask.reset();
+ if (slot < IBUFFER_HALF_SIZE) m_next = 0; // only reset for primary half
+ }
+ void ibuffer_fill(unsigned slot, const warp_inst_t *pI, unsigned split_id,
+ const active_mask_t &split_mask) {
+ assert(slot < IBUFFER_SIZE);
+ m_ibuffer[slot].m_inst = pI;
+ m_ibuffer[slot].m_valid = true;
+ m_ibuffer[slot].m_split_id = split_id;
+ m_ibuffer[slot].m_split_mask = split_mask;
+ if (slot < IBUFFER_HALF_SIZE) m_next = 0; // only reset for primary half
}
bool ibuffer_empty() const {
for (unsigned i = 0; i < IBUFFER_SIZE; i++)
if (m_ibuffer[i].m_valid) return false;
return true;
}
+ bool ibuffer_half_empty(unsigned half) const {
+ unsigned start = half * IBUFFER_HALF_SIZE;
+ for (unsigned i = start; i < start + IBUFFER_HALF_SIZE; i++)
+ if (m_ibuffer[i].m_valid) return false;
+ return true;
+ }
+ bool ibuffer_any_half_empty() const {
+ return ibuffer_half_empty(0) || ibuffer_half_empty(1);
+ }
void ibuffer_flush() {
for (unsigned i = 0; i < IBUFFER_SIZE; i++) {
+ if (m_ibuffer[i].m_valid) {
+ dec_inst_in_pipeline();
+ }
+ m_ibuffer[i].m_inst = NULL;
+ m_ibuffer[i].m_valid = false;
+ m_ibuffer[i].m_split_id = (unsigned)-1;
+ }
+ for (unsigned h = 0; h < IBUFFER_NUM_HALVES; h++)
+ m_ibuffer_halves[h].m_assigned = false;
+ }
+ void ibuffer_flush_half(unsigned half) {
+ unsigned start = half * IBUFFER_HALF_SIZE;
+ for (unsigned i = start; i < start + IBUFFER_HALF_SIZE; i++) {
if (m_ibuffer[i].m_valid) dec_inst_in_pipeline();
m_ibuffer[i].m_inst = NULL;
m_ibuffer[i].m_valid = false;
+ m_ibuffer[i].m_split_id = (unsigned)-1;
}
+ m_ibuffer_halves[half].m_assigned = false;
}
const warp_inst_t *ibuffer_next_inst() { return m_ibuffer[m_next].m_inst; }
bool ibuffer_next_valid() { return m_ibuffer[m_next].m_valid; }
+ unsigned ibuffer_next_split_id() const {
+ return m_ibuffer[m_next].m_split_id;
+ }
+ const active_mask_t &ibuffer_next_split_mask() const {
+ return m_ibuffer[m_next].m_split_mask;
+ }
void ibuffer_free() {
m_ibuffer[m_next].m_inst = NULL;
m_ibuffer[m_next].m_valid = false;
}
- void ibuffer_step() { m_next = (m_next + 1) % IBUFFER_SIZE; }
+ void ibuffer_step() { m_next = (m_next + 1) % IBUFFER_HALF_SIZE; }
+ unsigned get_ibuffer_next() const { return m_next; }
+ // Direct slot access for co-issue pass
+ bool ibuffer_slot_valid(unsigned slot) const {
+ return m_ibuffer[slot].m_valid;
+ }
+ const warp_inst_t *ibuffer_slot_inst(unsigned slot) const {
+ return m_ibuffer[slot].m_inst;
+ }
+ unsigned ibuffer_slot_split_id(unsigned slot) const {
+ return m_ibuffer[slot].m_split_id;
+ }
+ const active_mask_t &ibuffer_slot_split_mask(unsigned slot) const {
+ return m_ibuffer[slot].m_split_mask;
+ }
+ void ibuffer_free_slot(unsigned slot) {
+ m_ibuffer[slot].m_inst = NULL;
+ m_ibuffer[slot].m_valid = false;
+ }
+ // Half assignment tracking
+ void ibuffer_assign_half(unsigned half, unsigned split_id,
+ const active_mask_t &mask) {
+ m_ibuffer_halves[half].m_assigned_split_id = split_id;
+ m_ibuffer_halves[half].m_assigned_mask = mask;
+ m_ibuffer_halves[half].m_assigned = true;
+ }
+ bool ibuffer_half_assigned(unsigned half) const {
+ return m_ibuffer_halves[half].m_assigned;
+ }
+ unsigned ibuffer_half_split_id(unsigned half) const {
+ return m_ibuffer_halves[half].m_assigned_split_id;
+ }
+ const active_mask_t &ibuffer_half_mask(unsigned half) const {
+ return m_ibuffer_halves[half].m_assigned_mask;
+ }
bool imiss_pending() const { return m_imiss_pending; }
void set_imiss_pending() { m_imiss_pending = true; }
@@ -285,7 +360,9 @@ class shd_warp_t {
}
private:
- static const unsigned IBUFFER_SIZE = 2;
+ static const unsigned IBUFFER_SIZE = 4;
+ static const unsigned IBUFFER_HALF_SIZE = 2;
+ static const unsigned IBUFFER_NUM_HALVES = 2;
class shader_core_ctx *m_shader;
unsigned long long m_streamID;
unsigned m_cta_id;
@@ -303,13 +380,24 @@ class shd_warp_t {
ibuffer_entry() {
m_valid = false;
m_inst = NULL;
+ m_split_id = (unsigned)-1;
}
const warp_inst_t *m_inst;
bool m_valid;
+ unsigned m_split_id; // splits table entry this belongs to
+ active_mask_t m_split_mask; // the split's active mask at decode time
+ };
+
+ struct ibuffer_half_t {
+ ibuffer_half_t() : m_assigned(false), m_assigned_split_id((unsigned)-1) {}
+ bool m_assigned;
+ unsigned m_assigned_split_id;
+ active_mask_t m_assigned_mask;
};
warp_inst_t m_inst_at_barrier;
ibuffer_entry m_ibuffer[IBUFFER_SIZE];
+ ibuffer_half_t m_ibuffer_halves[IBUFFER_NUM_HALVES];
unsigned m_next;
unsigned m_n_atomic; // number of outstanding atomic operations
@@ -1150,19 +1238,27 @@ struct insn_latency_info {
};
struct ifetch_buffer_t {
- ifetch_buffer_t() { m_valid = false; }
+ ifetch_buffer_t() : m_valid(false), m_ibuffer_half(0),
+ m_split_id((unsigned)-1) { m_split_mask.reset(); }
- ifetch_buffer_t(address_type pc, unsigned nbytes, unsigned warp_id) {
- m_valid = true;
- m_pc = pc;
- m_nbytes = nbytes;
- m_warp_id = warp_id;
- }
+ ifetch_buffer_t(address_type pc, unsigned nbytes, unsigned warp_id)
+ : m_valid(true), m_pc(pc), m_nbytes(nbytes), m_warp_id(warp_id),
+ m_ibuffer_half(0), m_split_id((unsigned)-1) { m_split_mask.reset(); }
+
+ ifetch_buffer_t(address_type pc, unsigned nbytes, unsigned warp_id,
+ unsigned ibuffer_half, unsigned split_id,
+ const active_mask_t &split_mask)
+ : m_valid(true), m_pc(pc), m_nbytes(nbytes), m_warp_id(warp_id),
+ m_ibuffer_half(ibuffer_half), m_split_id(split_id),
+ m_split_mask(split_mask) {}
bool m_valid;
address_type m_pc;
unsigned m_nbytes;
unsigned m_warp_id;
+ unsigned m_ibuffer_half; // which I-Buffer half to fill (0 or 1)
+ unsigned m_split_id; // splits table entry
+ active_mask_t m_split_mask; // the split's active mask
};
class shader_core_config;
@@ -2501,6 +2597,15 @@ class shader_core_ctx : public core_t {
bool pending_reconvergence(unsigned wid);
bool warp_blocked(unsigned wid);
bool warp_valid(unsigned wid);
+ // SIMD lane partitioning: secondary split access
+ bool has_secondary_split(unsigned wid);
+ bool get_secondary_split_info(unsigned wid, unsigned *pc, unsigned *rpc,
+ unsigned *split_id, simt_mask_t *mask);
+ bool is_split_valid(unsigned wid, unsigned split_id);
+ void get_split_info(unsigned wid, unsigned split_id, unsigned *pc,
+ simt_mask_t *mask);
+ bool move_split_to_front(unsigned wid, unsigned split_id);
+ simt_tables *get_simt_tables(unsigned wid) { return m_simt_tables[wid]; }
bool push_to_st_response_fifo(unsigned wid, unsigned entry);
bool push_to_rt_response_fifo(unsigned wid, unsigned entry);
void update_st_size(unsigned n);
@@ -2538,7 +2643,8 @@ class shader_core_ctx : public core_t {
unsigned warp_id, unsigned sch_id);
void co_issue_warp(warp_inst_t *composite, const warp_inst_t *next_inst,
const active_mask_t &active_mask, unsigned warp_id,
- unsigned sch_id, unsigned start_set = 0);
+ unsigned sch_id, unsigned start_set = 0,
+ unsigned split_id = (unsigned)-1);
void create_front_pipeline();
void create_schedulers();
@@ -2621,6 +2727,7 @@ class shader_core_ctx : public core_t {
std::vector<shd_warp_t *> m_warp; // per warp information array
barrier_set_t m_barriers;
ifetch_buffer_t m_inst_fetch_buffer;
+ ifetch_buffer_t m_inst_fetch_buffer_secondary; // for secondary split
std::vector<register_set> m_pipeline_reg;
Scoreboard *m_scoreboard;
opndcoll_rfu_t m_operand_collector;