aboutsummaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-sim.cc12
-rw-r--r--src/gpgpu-sim/gpu-sim.h9
-rw-r--r--src/gpgpu-sim/shader.cc31
-rw-r--r--src/gpgpu-sim/shader.h30
4 files changed, 50 insertions, 32 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 96d5c62..77c6aae 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -174,10 +174,6 @@ int g_ptx_inst_debug_to_file;
char* g_ptx_inst_debug_file;
int g_ptx_inst_debug_thread_uid;
-int g_ptx_convert_to_ptxplus;
-int g_ptx_save_converted_ptxplus;
-unsigned g_ptx_force_max_capability;
-
void visualizer_options(option_parser_t opp);
void gpgpu_sim::reg_options(option_parser_t opp)
@@ -371,15 +367,15 @@ void gpgpu_sim::reg_options(option_parser_t opp)
"Thread UID for executed instructions' debug output",
"1");
option_parser_register(opp, "-gpgpu_ptx_convert_to_ptxplus", OPT_BOOL,
- &g_ptx_convert_to_ptxplus,
+ &m_ptx_convert_to_ptxplus,
"Convert embedded ptx to ptxplus",
"0");
option_parser_register(opp, "-gpgpu_ptx_save_converted_ptxplus", OPT_BOOL,
- &g_ptx_save_converted_ptxplus,
+ &m_ptx_save_converted_ptxplus,
"Saved converted ptxplus to a file",
"0");
option_parser_register(opp, "-gpgpu_ptx_force_max_capability", OPT_UINT32,
- &g_ptx_force_max_capability,
+ &m_ptx_force_max_capability,
"Force maximum compute capability",
"0");
option_parser_register(opp, "-gpgpu_operand_collector", OPT_BOOL, &m_shader_config->gpgpu_operand_collector,
@@ -1080,7 +1076,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
for (unsigned i = start_thread; i<end_thread; i++) {
m_thread[i].m_cta_id = free_cta_hw_id;
unsigned warp_id = i/m_config->warp_size;
- nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i].m_functional_model_thread_state,m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id);
+ nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i].m_functional_model_thread_state,m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id,m_gpu);
warps.set( warp_id );
}
assert( nthreads_in_block > 0 && nthreads_in_block <= m_config->n_thread_per_shader); // should be at least one, but less than max
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index ac03cbc..d690fab 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -178,7 +178,7 @@ extern int g_ptx_inst_debug_thread_uid;
-class gpgpu_sim {
+class gpgpu_sim : public gpgpu_t {
public:
gpgpu_sim();
@@ -211,6 +211,10 @@ public:
void gpu_print_stat() const;
void dump_pipeline( int mask, int s, int m ) const;
+ unsigned get_forced_capability() const { return m_ptx_force_max_capability; }
+ bool convert_to_ptxplus() const { return m_ptx_convert_to_ptxplus; }
+ bool saved_converted_ptxplus() const { return m_ptx_save_converted_ptxplus; }
+
private:
// clocks
void init_clock_domains(void);
@@ -271,6 +275,9 @@ private:
// options
bool gpu_deadlock_detect;
+ int m_ptx_convert_to_ptxplus;
+ int m_ptx_save_converted_ptxplus;
+ unsigned m_ptx_force_max_capability;
// stats
struct shader_core_stats *m_shader_stats;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 061952a..54e4ffa 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -593,7 +593,7 @@ void pdom_warp_ctx_t::print (FILE *fout) const
}
for (unsigned m=1,j=0; j<m_warp_size; j++, m<<=1)
fprintf(fout, "%c", ((warp->m_active_mask[k] & m)?'1':'0') );
- fprintf(fout, " pc: %4u", warp->m_pc[k] );
+ 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] );
} else {
@@ -639,13 +639,14 @@ void shader_core_ctx::fetch_new()
// decode 1 or 2 instructions and place them into ibuffer
address_type pc = m_inst_fetch_buffer.m_pc;
const warp_inst_t* pI1 = ptx_fetch_inst(pc);
- assert(pI1);
m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1);
m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline();
- const warp_inst_t* pI2 = ptx_fetch_inst(pc+pI1->isize);
- if( pI2 ) {
- m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2);
- m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline();
+ if( pI1 ) {
+ const warp_inst_t* pI2 = ptx_fetch_inst(pc+pI1->isize);
+ if( pI2 ) {
+ m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2);
+ m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline();
+ }
}
m_inst_fetch_buffer.m_valid = false;
}
@@ -767,10 +768,12 @@ void shader_core_ctx::decode_new()
unsigned issued=0;
while( !m_warp[warp_id].waiting() && !m_warp[warp_id].ibuffer_empty() && (checked < 2) && (issued < 2) ) {
unsigned active_mask = m_pdom_warp[warp_id]->get_active_mask();
- const warp_inst_t *pI = m_warp[warp_id].ibuffer_next();
+ const warp_inst_t *pI = m_warp[warp_id].ibuffer_next_inst();
+ bool valid = m_warp[warp_id].ibuffer_next_valid();
unsigned pc,rpc;
m_pdom_warp[warp_id]->get_pdom_stack_top_info(&pc,&rpc);
if( pI ) {
+ assert(valid);
if( pc != pI->pc ) {
// control hazard
m_warp[warp_id].set_next_pc(pc);
@@ -785,6 +788,10 @@ void shader_core_ctx::decode_new()
issued++;
}
}
+ } else if( valid ) {
+ // this case can happen after a return instruction in diverged warp
+ m_warp[warp_id].set_next_pc(pc);
+ m_warp[warp_id].ibuffer_flush();
}
m_warp[warp_id].ibuffer_step();
checked++;
@@ -792,7 +799,7 @@ void shader_core_ctx::decode_new()
if ( issued ) {
m_last_warp_issued=warp_id;
break;
- }
+ }
}
}
@@ -852,7 +859,9 @@ mshr_entry* mshr_shader_unit::add_mshr(mem_access_t &access, warp_inst_t* warp)
// creates an mshr based on the access struct information
mshr_entry* mshr = alloc_free_mshr(access.space == tex_space);
mshr->init(access.addr,access.iswrite,access.space,warp->warp_id());
- mshr->add_inst(*warp);
+ warp_inst_t inst = *warp;
+ inst.set_active(access.warp_indices);
+ mshr->add_inst(inst);
if( m_shader_config->gpgpu_interwarp_mshr_merge ) {
mshr_entry* mergehit = m_mshr_lookup.shader_get_mergeable_mshr(mshr);
if (mergehit) {
@@ -2025,8 +2034,10 @@ void shd_warp_t::print_ibuffer( FILE *fout ) const
{
fprintf(fout," ibuffer[%2u] : ", m_warp_id );
for( unsigned i=0; i < IBUFFER_SIZE; i++) {
- const inst_t *inst = m_ibuffer[i];
+ const inst_t *inst = m_ibuffer[i].m_inst;
if( inst ) inst->print_insn(fout);
+ else if( m_ibuffer[i].m_valid )
+ fprintf(fout," <invalid instruction> ");
else fprintf(fout," <empty> ");
}
fprintf(fout,"\n");
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index d9a8825..cdbaf37 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -146,8 +146,6 @@ public:
m_done_exit=false;
m_last_fetch=0;
m_next=0;
- for(unsigned i=0;i<IBUFFER_SIZE;i++)
- m_ibuffer[i]=NULL;
}
void init( address_type start_pc, unsigned cta_id, unsigned wid, unsigned active )
{
@@ -186,31 +184,32 @@ public:
void ibuffer_fill( unsigned slot, const warp_inst_t *pI )
{
assert(slot < IBUFFER_SIZE );
- m_ibuffer[slot]=pI;
+ m_ibuffer[slot].m_inst=pI;
+ m_ibuffer[slot].m_valid=true;
m_next=0;
}
bool ibuffer_empty() const
{
for( unsigned i=0; i < IBUFFER_SIZE; i++)
- if(m_ibuffer[i])
+ if(m_ibuffer[i].m_valid)
return false;
return true;
}
void ibuffer_flush()
{
for(unsigned i=0;i<IBUFFER_SIZE;i++) {
- if( m_ibuffer[i] )
+ if( m_ibuffer[i].m_valid )
dec_inst_in_pipeline();
- m_ibuffer[i]=NULL;
+ m_ibuffer[i].m_inst=NULL;
+ m_ibuffer[i].m_valid=false;
}
}
- const warp_inst_t *ibuffer_next()
- {
- return m_ibuffer[m_next];
- }
+ 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; }
void ibuffer_free()
{
- m_ibuffer[m_next] = NULL;
+ m_ibuffer[m_next].m_inst = NULL;
+ m_ibuffer[m_next].m_valid = false;
}
void ibuffer_step()
{
@@ -252,8 +251,13 @@ private:
unsigned n_completed; // number of threads in warp completed
class mshr_entry *m_imiss_pending;
-
- const warp_inst_t *m_ibuffer[IBUFFER_SIZE];
+
+ struct ibuffer_entry {
+ ibuffer_entry() { m_valid = false; m_inst = NULL; }
+ const warp_inst_t *m_inst;
+ bool m_valid;
+ };
+ ibuffer_entry m_ibuffer[IBUFFER_SIZE];
unsigned m_next;
unsigned m_n_atomic; // number of outstanding atomic operations