summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorInderpreet Singh <[email protected]>2012-07-18 23:17:29 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:47:33 -0700
commit8d59181b80697dfc717abcd55da9c899e4cf0d07 (patch)
treee34982e972f5cea3585a902e06bc38a006b042f0 /src
parent896e5c9a34e1b1230a67fb714d8290cd6f7f979b (diff)
Copied in Arun's SIMT stack fix for recursive calls (CL8574)
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 13410]
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.cc72
-rw-r--r--src/abstract_hardware_model.h15
-rw-r--r--src/cuda-sim/cuda-sim.cc17
-rw-r--r--src/cuda-sim/ptx_ir.cc13
4 files changed, 99 insertions, 18 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 396e45a..b86e750 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -533,24 +533,29 @@ simt_stack::simt_stack( unsigned wid, unsigned warpSize)
{
m_warp_id=wid;
m_warp_size = warpSize;
+ m_max_stack_size = m_warp_size * 4; // this choice is arbitrary. stack size can grow arbitrarily with deeper call hierarchies.
+ // TODO: expandable stack implementation
m_stack_top = 0;
- m_pc = (address_type*)calloc(m_warp_size * 2, sizeof(address_type));
- m_calldepth = (unsigned int*)calloc(m_warp_size * 2, sizeof(unsigned int));
- m_active_mask = new simt_mask_t[m_warp_size * 2];
- m_recvg_pc = (address_type*)calloc(m_warp_size * 2, sizeof(address_type));
- m_branch_div_cycle = (unsigned long long *)calloc(m_warp_size * 2, sizeof(unsigned long long ));
+ m_pc = (address_type*)calloc(m_max_stack_size, sizeof(address_type));
+ m_calldepth = (unsigned int*)calloc(m_max_stack_size, sizeof(unsigned int));
+ m_active_mask = new simt_mask_t[m_max_stack_size];
+ m_recvg_pc = (address_type*)calloc(m_max_stack_size, sizeof(address_type));
+ m_branch_div_cycle = (unsigned long long *)calloc(m_max_stack_size, sizeof(unsigned long long ));
+ m_type = (stack_entry_type *) calloc(m_max_stack_size, sizeof(stack_entry_type));
reset();
}
void simt_stack::reset()
{
m_stack_top = 0;
- memset(m_pc, -1, m_warp_size * 2 * sizeof(address_type));
- memset(m_calldepth, 0, m_warp_size * 2 * sizeof(unsigned int));
- memset(m_recvg_pc, -1, m_warp_size * 2 * sizeof(address_type));
- memset(m_branch_div_cycle, 0, m_warp_size * 2 * sizeof(unsigned long long ));
- for( unsigned i=0; i < 2*m_warp_size; i++ )
+ memset(m_pc, -1, m_max_stack_size * sizeof(address_type));
+ memset(m_calldepth, 0, m_max_stack_size * sizeof(unsigned int));
+ memset(m_recvg_pc, -1, m_max_stack_size * sizeof(address_type));
+ memset(m_branch_div_cycle, 0, m_max_stack_size * sizeof(unsigned long long ));
+ for( unsigned i=0; i < m_max_stack_size; i++ ) {
m_active_mask[i].reset();
+ m_type[i] = NORMAL;
+ }
}
void simt_stack::launch( address_type start_pc, const simt_mask_t &active_mask )
@@ -590,9 +595,9 @@ void simt_stack::print (FILE *fout) const
fprintf(fout, "%c", (warp->m_active_mask[k].test(j)?'1':'0') );
fprintf(fout, " pc: 0x%03x", warp->m_pc[k] );
if ( warp->m_recvg_pc[k] == (unsigned)-1 ) {
- fprintf(fout," rp: ---- cd: %2u ", warp->m_calldepth[k] );
+ fprintf(fout," rp: ---- tp: %s cd: %2u ", (warp->m_type[k]==CALL?"C":"N"), warp->m_calldepth[k] );
} else {
- fprintf(fout," rp: %4u cd: %2u ", warp->m_recvg_pc[k], warp->m_calldepth[k] );
+ fprintf(fout," rp: %4u tp: %s cd: %2u ", warp->m_recvg_pc[k], (warp->m_type[k]==CALL?"C":"N"), warp->m_calldepth[k] );
}
if ( warp->m_branch_div_cycle[k] != 0 ) {
fprintf(fout," bd@%6u ", (unsigned) warp->m_branch_div_cycle[k] );
@@ -604,7 +609,7 @@ void simt_stack::print (FILE *fout) const
}
}
-void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc )
+void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc, op_type next_inst_op )
{
int stack_top = m_stack_top;
@@ -613,6 +618,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre
simt_mask_t top_active_mask = m_active_mask[stack_top];
address_type top_recvg_pc = m_recvg_pc[stack_top];
address_type top_pc = m_pc[stack_top]; // the pc of the instruction just executed
+ stack_entry_type top_type = m_type[stack_top];
assert(top_active_mask.any());
@@ -639,9 +645,43 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre
}
}
+ // HANDLE THE SPECIAL CASES FIRST
+ if (next_inst_op== CALL_OPS)
+ {
+ // Since call is not a divergent instruction, all threads should have executed a call instruction
+ assert(top_active_mask.any() == false);
+ stack_top += 1;
+
+ m_active_mask[stack_top] = tmp_active_mask;
+ m_pc[stack_top]=tmp_next_pc;
+ m_type[stack_top]= CALL;
+ m_recvg_pc[stack_top] = -1;
+ m_stack_top = stack_top;
+ return;
+
+ } else if(next_inst_op == RET_OPS && top_type==CALL) {
+ // pop the CALL Entry
+ assert(top_active_mask.any() == false);
+
+ m_type[stack_top]= NORMAL; // RESET THE STACK ENTRY FOR FUTURE USE
+
+ stack_top -= 1; // REMOVE The top stack entry
+ m_stack_top = stack_top;
+ m_pc[stack_top]=tmp_next_pc;// set the PC of the stack top entry to return PC from the call stack;
+ // Check if the New top of the stack is reconverging
+ if (tmp_next_pc == m_recvg_pc[stack_top] && m_type[stack_top]!=CALL)
+ {
+ assert(m_type[stack_top]==NORMAL);
+ stack_top -= 1; // REMOVE this entry as well
+ m_stack_top = stack_top;
+ }
+ return;
+ }
+
// discard the new entry if its PC matches with reconvergence PC
// that automatically reconverges the entry
- if (tmp_next_pc == top_recvg_pc) continue;
+ // If the top stack entry is CALL, dont reconverge.
+ if (tmp_next_pc == top_recvg_pc && (top_type != CALL)) continue;
// this new entry is not converging
// if this entry does not include thread from the warp, divergence occurs
@@ -674,7 +714,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre
m_stack_top = stack_top - 1;
assert(m_stack_top >= 0);
- assert(m_stack_top < m_warp_size * 2);
+ assert(m_stack_top < m_max_stack_size);
if (warp_diverged) {
ptx_file_line_stats_add_warp_divergence(top_pc, 1);
@@ -714,7 +754,7 @@ for (unsigned i = 0; i < warpSize; i++) {
next_pc.push_back( m_thread[wtid+i]->get_pc() );
}
}
-m_simt_stack[warpId]->update(thread_done,next_pc,inst->reconvergence_pc);
+m_simt_stack[warpId]->update(thread_done,next_pc,inst->reconvergence_pc, inst->op);
}
//! Get the warp to be executed using the data taken form the SIMT stack
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 1fc10b9..4cde89a 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -64,7 +64,9 @@ enum uarch_op_t {
STORE_OP,
BRANCH_OP,
BARRIER_OP,
- MEMORY_BARRIER_OP
+ MEMORY_BARRIER_OP,
+ CALL_OPS,
+ RET_OPS
};
typedef enum uarch_op_t op_type;
@@ -245,7 +247,7 @@ public:
void reset();
void launch( address_type start_pc, const simt_mask_t &active_mask );
- void update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc );
+ void update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc, op_type next_inst_op );
const simt_mask_t &get_active_mask() const;
void get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ) const;
@@ -256,12 +258,19 @@ protected:
unsigned m_warp_id;
unsigned m_stack_top;
unsigned m_warp_size;
+ unsigned m_max_stack_size;
address_type *m_pc;
simt_mask_t *m_active_mask;
address_type *m_recvg_pc;
unsigned int *m_calldepth;
+ enum stack_entry_type {
+ NORMAL = 0,
+ CALL
+ };
+ stack_entry_type *m_type;
+
unsigned long long *m_branch_div_cycle;
};
@@ -683,6 +692,7 @@ public:
m_per_scalar_thread_valid=false;
m_mem_accesses_created=false;
m_cache_hit=false;
+ m_is_printf=false;
}
virtual ~warp_inst_t(){
}
@@ -814,6 +824,7 @@ protected:
unsigned long long issue_cycle;
unsigned cycles; // used for implementing initiation interval delay
bool m_isatomic;
+ bool m_is_printf;
unsigned m_warp_id;
const core_config *m_config;
active_mask_t m_warp_active_mask;
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 252b230..e17877b 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -499,6 +499,23 @@ void ptx_instruction::set_opcode_and_latency()
case ATOM_OP: op = LOAD_OP; break;
case BAR_OP: op = BARRIER_OP; break;
case MEMBAR_OP: op = MEMORY_BARRIER_OP; break;
+ case CALL_OP:
+ {
+ if(m_is_printf)
+ op = ALU_OP;
+ else
+ op = CALL_OPS;
+ break;
+ }
+ case CALLP_OP:
+ {
+ if(m_is_printf)
+ op = ALU_OP;
+ else
+ op = CALL_OPS;
+ break;
+ }
+ case RET_OP: op = RET_OPS;break;
case ADD_OP: case ADDP_OP: case ADDC_OP: case SUB_OP: case SUBC_OP:
//ADD,SUB latency
switch(get_type()){
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 102ae40..61b45e3 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -1162,6 +1162,19 @@ ptx_instruction::ptx_instruction( int opcode,
m_source_file = file?file:"<unknown>";
m_source_line = line;
m_source = source;
+
+ if (opcode == CALL_OP) {
+ const operand_info &target = func_addr();
+ assert( target.is_function_address() );
+ const symbol *func_addr = target.get_symbol();
+ const function_info *target_func = func_addr->get_pc();
+ std::string fname = target_func->get_name();
+
+ if (fname =="vprintf"){
+ m_is_printf = true;
+ }
+
+ }
}
void ptx_instruction::print_insn() const