diff options
| author | Tor Aamodt <[email protected]> | 2010-10-22 14:22:21 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-10-22 14:22:21 -0800 |
| commit | 4da926e61569a069bac229e8ba649e600fc78a04 (patch) | |
| tree | cdb7fb44f15cf844c587bf2c92b37d3d2412c152 | |
| parent | dc93f319051a9a9936a02cd9c1f7843a382a2da0 (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.cc | 4 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 89 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 24 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.cc | 8 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 30 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 8 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 6 |
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(); |
