summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-22 14:22:21 -0800
committerTor Aamodt <[email protected]>2010-10-22 14:22:21 -0800
commit4da926e61569a069bac229e8ba649e600fc78a04 (patch)
treecdb7fb44f15cf844c587bf2c92b37d3d2412c152
parentdc93f319051a9a9936a02cd9c1f7843a382a2da0 (diff)
enables global loads/stores for ptxplus
passing CUDA 3.1 and ptxplus correlation correlation back to around 0.89 on ptxplus vs quadro fx5800 [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7898]
-rw-r--r--src/abstract_hardware_model.cc4
-rw-r--r--src/cuda-sim/cuda-sim.cc89
-rw-r--r--src/cuda-sim/instructions.cc24
-rw-r--r--src/cuda-sim/ptx_ir.cc8
-rw-r--r--src/cuda-sim/ptx_ir.h30
-rw-r--r--src/cuda-sim/ptx_parser.cc8
-rw-r--r--src/gpgpu-sim/shader.cc6
7 files changed, 99 insertions, 70 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index ad5c983..dfe4b36 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -40,8 +40,10 @@ void warp_inst_t::generate_mem_accesses()
{
if( empty() || op == MEMORY_BARRIER_OP || m_mem_accesses_created )
return;
- if ( !( (op == LOAD_OP) || (op == STORE_OP) || (op == MEMORY_BARRIER_OP) ) )
+ if ( !((op == LOAD_OP) || (op == STORE_OP)) )
return;
+ if( m_warp_active_mask.count() == 0 )
+ return; // predicated off
assert( is_load() || is_store() );
assert( m_per_scalar_thread_valid ); // need address information per thread
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index e61659c..d429dc3 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -438,11 +438,16 @@ void ptx_print_insn( address_type pc, FILE *fp )
finfo->print_insn(pc,fp);
}
-void ptx_instruction::get_opcode_info()
+void ptx_instruction::set_opcode_and_latency()
{
op = ALU_OP;
initiation_interval = latency = 1;
switch( m_opcode ) {
+ case MOV_OP:
+ assert( !(has_memory_read() && has_memory_write()) );
+ if ( has_memory_read() ) op = LOAD_OP;
+ if ( has_memory_write() ) op = STORE_OP;
+ break;
case LD_OP: op = LOAD_OP; break;
case ST_OP: op = STORE_OP; break;
case BRA_OP: op = BRANCH_OP; break;
@@ -506,6 +511,37 @@ void ptx_thread_info::ptx_fetch_inst( inst_t &inst ) const
assert( inst.valid() );
}
+static unsigned datatype2size( unsigned data_type )
+{
+ unsigned data_size;
+ switch ( data_type ) {
+ case B8_TYPE:
+ case S8_TYPE:
+ case U8_TYPE:
+ data_size = 1; break;
+ case B16_TYPE:
+ case S16_TYPE:
+ case U16_TYPE:
+ case F16_TYPE:
+ data_size = 2; break;
+ case B32_TYPE:
+ case S32_TYPE:
+ case U32_TYPE:
+ case F32_TYPE:
+ data_size = 4; break;
+ case B64_TYPE:
+ case BB64_TYPE:
+ case S64_TYPE:
+ case U64_TYPE:
+ case F64_TYPE:
+ data_size = 8; break;
+ case BB128_TYPE:
+ data_size = 16; break;
+ default: assert(0); break;
+ }
+ return data_size;
+}
+
void ptx_instruction::pre_decode()
{
pc = m_PC;
@@ -520,6 +556,14 @@ void ptx_instruction::pre_decode()
pred = 0;
ar1 = 0;
ar2 = 0;
+ space = m_space_spec;
+ memory_op = no_memory_op;
+ data_size = 0;
+ if ( has_memory_read() || has_memory_write() ) {
+ unsigned to_type = get_type();
+ data_size = datatype2size(to_type);
+ memory_op = has_memory_read() ? memory_load : memory_store;
+ }
bool has_dst = false ;
@@ -532,13 +576,12 @@ void ptx_instruction::pre_decode()
break;
}
- get_opcode_info();
+ set_opcode_and_latency();
// Get register operands
int n=0,m=0;
ptx_instruction::const_iterator opr=op_iter_begin();
for ( ; opr != op_iter_end(); opr++, n++ ) { //process operands
-
const operand_info &o = *opr;
if ( has_dst && n==0 ) {
if ( o.is_reg() ) { //but is destination an actual register? (seems like it fails if it's a vector)
@@ -771,37 +814,6 @@ bool ptx_debug_exec_dump_cond(int thd_uid, addr_t pc)
return false;
}
-unsigned datatype2size( unsigned data_type )
-{
- unsigned data_size;
- switch ( data_type ) {
- case B8_TYPE:
- case S8_TYPE:
- case U8_TYPE:
- data_size = 1; break;
- case B16_TYPE:
- case S16_TYPE:
- case U16_TYPE:
- case F16_TYPE:
- data_size = 2; break;
- case B32_TYPE:
- case S32_TYPE:
- case U32_TYPE:
- case F32_TYPE:
- data_size = 4; break;
- case B64_TYPE:
- case BB64_TYPE:
- case S64_TYPE:
- case U64_TYPE:
- case F64_TYPE:
- data_size = 8; break;
- case BB128_TYPE:
- data_size = 16; break;
- default: assert(0); break;
- }
- return data_size;
-}
-
void init_inst_classification_stat()
{
static std::set<unsigned> init;
@@ -821,7 +833,6 @@ void init_inst_classification_stat()
void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
{
- inst.memory_op = no_memory_op;
bool skip = false;
int op_classification = 0;
addr_t pc = next_instr();
@@ -857,6 +868,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
if( skip ) {
inst.set_not_active(lane_id);
} else {
+ const ptx_instruction *pI_saved = pI;
ptx_instruction *pJ = NULL;
if( pI->get_opcode() == VOTE_OP ) {
pJ = new ptx_instruction(*pI);
@@ -870,6 +882,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
default: printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() ); break;
}
delete pJ;
+ pI = pI_saved;
// Run exit instruction if exit option included
if(pI->is_exit())
@@ -924,7 +937,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
if (pI->get_opcode() == TEX_OP) {
inst.set_addr(lane_id, last_eaddr() );
- inst.space = last_space();
+ assert( inst.space == last_space() );
unsigned to_type = pI->get_type();
switch ( to_type ) {
@@ -1002,8 +1015,8 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
if(!skip) {
inst.space = insn_space;
inst.set_addr(lane_id, insn_memaddr);
- inst.data_size = insn_data_size;
- inst.memory_op = insn_memory_op;
+ inst.data_size = insn_data_size; // simpleAtomicIntrinsics
+ assert( inst.memory_op == insn_memory_op );
}
} catch ( int x ) {
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 1ae1919..2b6ce9c 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -137,7 +137,7 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
ptx_reg_t result, tmp;
if(op.get_double_operand_type() == 0) {
- if(((opType != BB128_TYPE) && (opType != BB64_TYPE)) || (op.get_addr_space() != 0)) {
+ if(((opType != BB128_TYPE) && (opType != BB64_TYPE)) || (op.get_addr_space() != undefined_space)) {
if ( op.is_reg() ) {
result = get_reg( op.get_symbol() );
} else if ( op.is_builtin()) {
@@ -242,7 +242,7 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
finalResult.u64=0;
//complete other cases for reading from memory, such as reading from other const memory
- if((op.get_addr_space() == 1)&&(derefFlag)) {
+ if((op.get_addr_space() == global_space)&&(derefFlag)) {
// global memory - g[4], g[$r0]
mem = thread->get_global_memory();
type_info_key::type_decode(opType,size,t);
@@ -252,7 +252,7 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
if( opType == S16_TYPE || opType == S32_TYPE )
sign_extend(finalResult,size,dstInfo);
- } else if((op.get_addr_space() == 2)&&(derefFlag)) {
+ } else if((op.get_addr_space() == shared_space)&&(derefFlag)) {
// shared memory - s[4], s[$r0]
mem = thread->m_shared_mem;
type_info_key::type_decode(opType,size,t);
@@ -262,7 +262,7 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
if( opType == S16_TYPE || opType == S32_TYPE )
sign_extend(finalResult,size,dstInfo);
- } else if((op.get_addr_space() == 3)&&(derefFlag)) {
+ } else if((op.get_addr_space() == const_space)&&(derefFlag)) {
// const memory - ce0c1[4], ce0c1[$r0]
mem = thread->get_global_memory();
type_info_key::type_decode(opType,size,t);
@@ -271,7 +271,7 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
thread->m_last_memory_space = const_space;
if( opType == S16_TYPE || opType == S32_TYPE )
sign_extend(finalResult,size,dstInfo);
- } else if((op.get_addr_space() == 4)&&(derefFlag)) {
+ } else if((op.get_addr_space() == local_space)&&(derefFlag)) {
// local memory - l0[4], l0[$r0]
mem = thread->m_local_mem;
type_info_key::type_decode(opType,size,t);
@@ -432,7 +432,7 @@ void ptx_thread_info::set_operand_value( const operand_info &dst, const ptx_reg_
type_info_key::type_decode(type,size,t);
/*complete this section for other cases*/
- if(dst.get_addr_space() == 0)
+ if(dst.get_addr_space() == undefined_space)
{
ptx_reg_t setValue;
setValue.u64 = data.u64;
@@ -598,7 +598,7 @@ void ptx_thread_info::set_operand_value( const operand_info &dst, const ptx_reg_
}
// global memory - g[4], g[$r0]
- else if(dst.get_addr_space() == 1)
+ else if(dst.get_addr_space() == global_space)
{
dstData = thread->get_operand_value(dst, dst, type, thread, 0);
mem = thread->get_global_memory();
@@ -610,7 +610,7 @@ void ptx_thread_info::set_operand_value( const operand_info &dst, const ptx_reg_
}
// shared memory - s[4], s[$r0]
- else if(dst.get_addr_space() == 2)
+ else if(dst.get_addr_space() == shared_space)
{
dstData = thread->get_operand_value(dst, dst, type, thread, 0);
mem = thread->m_shared_mem;
@@ -622,7 +622,7 @@ void ptx_thread_info::set_operand_value( const operand_info &dst, const ptx_reg_
}
// local memory - l0[4], l0[$r0]
- else if(dst.get_addr_space() == 4)
+ else if(dst.get_addr_space() == local_space)
{
dstData = thread->get_operand_value(dst, dst, type, thread, 0);
mem = thread->m_local_mem;
@@ -3869,7 +3869,7 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, operand_inf
result.u64=0;
//complete other cases for reading from memory, such as reading from other const memory
- if(opInfo.get_addr_space() == 1)
+ if(opInfo.get_addr_space() == global_space)
{
mem = thread->get_global_memory();
type_info_key::type_decode(type,size,t);
@@ -3877,7 +3877,7 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, operand_inf
if( type == S16_TYPE || type == S32_TYPE )
sign_extend(result,size,dstInfo);
}
- else if(opInfo.get_addr_space() == 2)
+ else if(opInfo.get_addr_space() == shared_space)
{
mem = thread->m_shared_mem;
type_info_key::type_decode(type,size,t);
@@ -3887,7 +3887,7 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, operand_inf
sign_extend(result,size,dstInfo);
}
- else if(opInfo.get_addr_space() == 3)
+ else if(opInfo.get_addr_space() == const_space)
{
mem = thread->get_global_memory();
type_info_key::type_decode(type,size,t);
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 5def6db..fee0056 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -1143,7 +1143,15 @@ ptx_instruction::ptx_instruction( int opcode,
m_space_spec = space_spec;
if( ( opcode == ST_OP || opcode == LD_OP ) && (space_spec == undefined_space) ) {
m_space_spec = generic_space;
+ }
+ for( std::vector<operand_info>::const_iterator i=m_operands.begin(); i!=m_operands.end(); ++i) {
+ const operand_info &op = *i;
+ if( op.get_addr_space() != undefined_space )
+ m_space_spec = op.get_addr_space(); // TODO: can have more than one memory space for ptxplus (g8x) inst
}
+ if( opcode == TEX_OP )
+ m_space_spec = tex_space;
+
m_source_file = file?file:"<unknown>";
m_source_line = line;
m_source = source;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index cea2e2b..a8f9a7b 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -373,7 +373,7 @@ class operand_info {
public:
operand_info()
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -383,7 +383,7 @@ public:
}
operand_info( const symbol *addr )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -417,7 +417,7 @@ public:
}
operand_info( const symbol *addr1, const symbol *addr2 )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -437,7 +437,7 @@ public:
}
operand_info( int builtin_id, int dim_mod )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -453,7 +453,7 @@ public:
}
operand_info( const symbol *addr, int offset )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -469,7 +469,7 @@ public:
}
operand_info( unsigned x )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -485,7 +485,7 @@ public:
}
operand_info( int x )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -501,7 +501,7 @@ public:
}
operand_info( float x )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -517,7 +517,7 @@ public:
}
operand_info( double x )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -533,7 +533,7 @@ public:
}
operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4 )
{
- m_addr_space = 0;
+ m_addr_space = undefined_space;
m_operand_lohi = 0;
m_double_operand_type = 0;
m_operand_neg = false;
@@ -640,7 +640,7 @@ public:
// Memory operand with immediate access (ex. s[0x0004] or g[$r1+=0x0004])
bool is_memory_operand2() const {
- return (m_addr_space==1 || m_addr_space==2 || m_addr_space==3 || m_addr_space==4);
+ return (m_addr_space!=undefined_space);
}
bool is_literal() const { return m_type == int_t ||
@@ -699,8 +699,8 @@ public:
bool is_neg_pred() const { return m_neg_pred; }
bool is_valid() const { return m_valid; }
- void set_addr_space(int set_value) { m_addr_space = set_value; }
- int get_addr_space() const { return m_addr_space; }
+ void set_addr_space(enum _memory_space_t set_value) { m_addr_space = set_value; }
+ enum _memory_space_t get_addr_space() const { return m_addr_space; }
void set_operand_lohi(int set_value) { m_operand_lohi = set_value; }
int get_operand_lohi() const { return m_operand_lohi; }
void set_double_operand_type(int set_value) { m_double_operand_type = set_value; }
@@ -716,7 +716,7 @@ private:
bool m_vector;
enum operand_type m_type;
- int m_addr_space;
+ enum _memory_space_t m_addr_space;
int m_operand_lohi;
int m_double_operand_type;
bool m_operand_neg;
@@ -965,7 +965,7 @@ public:
}
private:
- void get_opcode_info();
+ void set_opcode_and_latency();
basic_block_t *m_basic_block;
unsigned m_uid;
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index 1081c3c..200c795 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -693,12 +693,12 @@ void change_memory_addr_space(const char *identifier)
assert( !g_operands.empty() );
if(!strcmp(identifier, "g"))
{
- g_operands.back().set_addr_space(1);
+ g_operands.back().set_addr_space(global_space);
recognizedType = true;
}
if(!strcmp(identifier, "s"))
{
- g_operands.back().set_addr_space(2);
+ g_operands.back().set_addr_space(shared_space);
recognizedType = true;
}
// For constants, check if the first character is 'c'
@@ -706,7 +706,7 @@ void change_memory_addr_space(const char *identifier)
strncpy(c, identifier, 1); c[1] = '\0';
if(!strcmp(c, "c"))
{
- g_operands.back().set_addr_space(3);
+ g_operands.back().set_addr_space(const_space);
parse_assert(g_current_symbol_table->lookup(identifier) != NULL, "Constant was not defined.");
g_operands.back().set_const_mem_offset(g_current_symbol_table->lookup(identifier)->get_address());
recognizedType = true;
@@ -716,7 +716,7 @@ void change_memory_addr_space(const char *identifier)
strncpy(l, identifier, 1); l[1] = '\0';
if(!strcmp(l, "l"))
{
- g_operands.back().set_addr_space(4);
+ g_operands.back().set_addr_space(local_space);
parse_assert(g_current_symbol_table->lookup(identifier) != NULL, "Local memory segment was not defined.");
g_operands.back().set_const_mem_offset(g_current_symbol_table->lookup(identifier)->get_address());
recognizedType = true;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 5c73126..79665cc 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -684,6 +684,8 @@ bool ldst_unit::constant_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail
{
if( inst.empty() || ((inst.space.get_type() != const_space) && (inst.space.get_type() != param_space_kernel)) )
return true;
+ if( inst.active_count() == 0 )
+ return true;
mem_stage_stall_type fail = process_memory_access_queue(m_L1C,inst);
if (fail != NO_RC_FAIL){
rc_fail = fail; //keep other fails if this didn't fail.
@@ -699,6 +701,8 @@ bool ldst_unit::texture_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail,
{
if( inst.empty() || inst.space.get_type() != tex_space )
return true;
+ if( inst.active_count() == 0 )
+ return true;
mem_stage_stall_type fail = process_memory_access_queue(m_L1T,inst);
if (fail != NO_RC_FAIL){
rc_fail = fail; //keep other fails if this didn't fail.
@@ -714,6 +718,8 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
(inst.space.get_type() != local_space) &&
(inst.space.get_type() != param_space_local)) )
return true;
+ if( inst.active_count() == 0 )
+ return true;
assert( !inst.accessq_empty() );
mem_stage_stall_type stall_cond = NO_RC_FAIL;
const mem_access_t &access = inst.accessq_back();