diff options
| -rw-r--r-- | cuobjdump_to_ptxplus/ptx_parser.h | 1 | ||||
| -rw-r--r-- | src/abstract_hardware_model.cc | 4 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 4 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 42 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 238 | ||||
| -rw-r--r-- | src/cuda-sim/opcodes.def | 2 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.l | 11 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.y | 2 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 6 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 14 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_sim.cc | 17 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_sim.h | 7 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 3 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 1 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 1 |
15 files changed, 334 insertions, 19 deletions
diff --git a/cuobjdump_to_ptxplus/ptx_parser.h b/cuobjdump_to_ptxplus/ptx_parser.h index 418a733..7cfb5c5 100644 --- a/cuobjdump_to_ptxplus/ptx_parser.h +++ b/cuobjdump_to_ptxplus/ptx_parser.h @@ -58,6 +58,7 @@ enum _memory_space_t { reg_space, local_space, shared_space, + sstarr_space, param_space_unclassified, param_space_kernel, /* global to all threads in a kernel : read-only */ param_space_local, /* local to a thread : read-writable */ diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index fe6f8ab..d668de7 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -213,6 +213,7 @@ void warp_inst_t::generate_mem_accesses() access_type = is_write? LOCAL_ACC_W: LOCAL_ACC_R; break; case shared_space: break; + case sstarr_space: break; default: assert(0); break; } @@ -220,7 +221,8 @@ void warp_inst_t::generate_mem_accesses() new_addr_type cache_block_size = 0; // in bytes switch( space.get_type() ) { - case shared_space: { + case shared_space: + case sstarr_space: { unsigned subwarp_size = m_config->warp_size / m_config->mem_warp_parts; unsigned total_accesses=0; for( unsigned subwarp=0; subwarp < m_config->mem_warp_parts; subwarp++ ) { diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index aaa4b00..607eda7 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -41,6 +41,7 @@ enum _memory_space_t { reg_space, local_space, shared_space, + sstarr_space, param_space_unclassified, param_space_kernel, /* global to all threads in a kernel : read-only */ param_space_local, /* local to a thread : read-writable */ @@ -602,6 +603,7 @@ public: return false; } enum _memory_space_t get_type() const { return m_type; } + void set_type( enum _memory_space_t t ) { m_type = t; } unsigned get_bank() const { return m_bank; } void set_bank( unsigned b ) { m_bank = b; } bool is_const() const { return (m_type == const_space) || (m_type == param_space_kernel); } @@ -835,7 +837,7 @@ public: int src[MAX_REG_OPERANDS]; } arch_reg; //int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation - unsigned latency; // operation latency + unsigned latency; // operation latency unsigned initiation_interval; unsigned data_size; // what is the size of the word being operated on? diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index d4ace76..b5b79e7 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -69,9 +69,9 @@ unsigned cdp_latency[5]; void ptx_opcocde_latency_options (option_parser_t opp) { option_parser_register(opp, "-ptx_opcode_latency_int", OPT_CSTR, &opcode_latency_int, - "Opcode latencies for integers <ADD,MAX,MUL,MAD,DIV>" - "Default 1,1,19,25,145", - "1,1,19,25,145"); + "Opcode latencies for integers <ADD,MAX,MUL,MAD,DIV,BSMAD>" + "Default 1,1,19,25,145,1", + "1,1,19,25,145,1"); option_parser_register(opp, "-ptx_opcode_latency_fp", OPT_CSTR, &opcode_latency_fp, "Opcode latencies for single precision floating points <ADD,MAX,MUL,MAD,DIV>" "Default 1,1,1,1,30", @@ -81,9 +81,9 @@ void ptx_opcocde_latency_options (option_parser_t opp) { "Default 8,8,8,8,335", "8,8,8,8,335"); option_parser_register(opp, "-ptx_opcode_initiation_int", OPT_CSTR, &opcode_initiation_int, - "Opcode initiation intervals for integers <ADD,MAX,MUL,MAD,DIV>" - "Default 1,1,4,4,32", - "1,1,4,4,32"); + "Opcode initiation intervals for integers <ADD,MAX,MUL,MAD,DIV,BSMAD>" + "Default 1,1,4,4,32,1", + "1,1,4,4,32,1"); option_parser_register(opp, "-ptx_opcode_initiation_fp", OPT_CSTR, &opcode_initiation_fp, "Opcode initiation intervals for single precision floating points <ADD,MAX,MUL,MAD,DIV>" "Default 1,1,1,1,5", @@ -581,15 +581,18 @@ void ptx_instruction::set_bar_type() abort(); } } + else if(m_opcode==SST_OP) { + bar_type = SYNC; + } } void ptx_instruction::set_opcode_and_latency() { - unsigned int_latency[5]; + unsigned int_latency[6]; unsigned fp_latency[5]; unsigned dp_latency[5]; - unsigned int_init[5]; + unsigned int_init[6]; unsigned fp_init[5]; unsigned dp_init[5]; /* @@ -598,19 +601,20 @@ void ptx_instruction::set_opcode_and_latency() * [2] MUL * [3] MAD * [4] DIV + * [5] BSMAD */ - sscanf(opcode_latency_int, "%u,%u,%u,%u,%u", + sscanf(opcode_latency_int, "%u,%u,%u,%u,%u,%u", &int_latency[0],&int_latency[1],&int_latency[2], - &int_latency[3],&int_latency[4]); + &int_latency[3],&int_latency[4],&int_latency[5]); sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u", &fp_latency[0],&fp_latency[1],&fp_latency[2], &fp_latency[3],&fp_latency[4]); sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u", &dp_latency[0],&dp_latency[1],&dp_latency[2], &dp_latency[3],&dp_latency[4]); - sscanf(opcode_initiation_int, "%u,%u,%u,%u,%u", + sscanf(opcode_initiation_int, "%u,%u,%u,%u,%u,%u", &int_init[0],&int_init[1],&int_init[2], - &int_init[3],&int_init[4]); + &int_init[3],&int_init[4],&int_init[5]); sscanf(opcode_initiation_fp, "%u,%u,%u,%u,%u", &fp_init[0],&fp_init[1],&fp_init[2], &fp_init[3],&fp_init[4]); @@ -647,6 +651,7 @@ void ptx_instruction::set_opcode_and_latency() case TEX_OP: op = LOAD_OP; mem_op=TEX; break; case ATOM_OP: op = LOAD_OP; break; case BAR_OP: op = BARRIER_OP; break; + case SST_OP: op = BARRIER_OP; break; case MEMBAR_OP: op = MEMORY_BARRIER_OP; break; case CALL_OP: { @@ -783,6 +788,10 @@ void ptx_instruction::set_opcode_and_latency() initiation_interval = dp_init[2]; op = SFU_OP; break; + case BSMAD_OP: + latency = int_latency[5]; + initiation_interval = int_init[5]; + break; case SHFL_OP: latency = 32; initiation_interval = 15; @@ -1459,6 +1468,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, std::list<ptx_thread_info *> &active_threads = kernel.active_threads(); static std::map<unsigned,memory_space*> shared_memory_lookup; + static std::map<unsigned,memory_space*> sstarr_memory_lookup; static std::map<unsigned,ptx_cta_info*> ptx_cta_lookup; static std::map<unsigned,ptx_warp_info*> ptx_warp_lookup; static std::map<unsigned,std::map<unsigned,memory_space*> > local_memory_lookup; @@ -1503,6 +1513,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, //initializing new CTA ptx_cta_info *cta_info = NULL; memory_space *shared_mem = NULL; + memory_space *sstarr_mem = NULL; unsigned cta_size = kernel.threads_per_cta(); unsigned max_cta_per_sm = num_threads/cta_size; // e.g., 256 / 48 = 5 @@ -1520,6 +1531,9 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, snprintf(buf,512,"shared_%u", sid); shared_mem = new memory_space_impl<16*1024>(buf,4); shared_memory_lookup[sm_idx] = shared_mem; + snprintf(buf,512,"sstarr_%u", sid); + sstarr_mem = new memory_space_impl<16*1024>(buf,4); + sstarr_memory_lookup[sm_idx] = sstarr_mem; cta_info = new ptx_cta_info(sm_idx); ptx_cta_lookup[sm_idx] = cta_info; } else { @@ -1528,6 +1542,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, sm_idx, sid, max_cta_per_sm ); } shared_mem = shared_memory_lookup[sm_idx]; + sstarr_mem = sstarr_memory_lookup[sm_idx]; cta_info = ptx_cta_lookup[sm_idx]; cta_info->check_cta_thread_status_and_reset(); } @@ -1540,7 +1555,6 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, kernel.increment_thread_id(); new_tid += tid; ptx_thread_info *thd = new ptx_thread_info(kernel); - ptx_warp_info *warp_info = NULL; if ( ptx_warp_lookup.find(hw_warp_id) == ptx_warp_lookup.end() ) { warp_info = new ptx_warp_info(); @@ -1569,9 +1583,11 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, thd->cpy_tid_to_reg(tid3d); thd->set_valid(); thd->m_shared_mem = shared_mem; + thd->m_sstarr_mem = sstarr_mem; function_info *finfo = thd->func_info(); symbol_table *st = finfo->get_symtab(); thd->func_info()->param_to_shared(thd->m_shared_mem,st); + thd->func_info()->param_to_shared(thd->m_sstarr_mem,st); thd->m_cta_info = cta_info; cta_info->add_thread(thd); thd->m_local_mem = local_mem; diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 011c285..159fd4c 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -135,6 +135,8 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in result.u64 = sym->get_address() + op.get_addr_offset(); } else if ( op.is_shared() ) { result.u64 = op.get_symbol()->get_address() + op.get_addr_offset(); + } else if ( op.is_sstarr() ) { + result.u64 = op.get_symbol()->get_address() + op.get_addr_offset(); } else { const char *name = op.name().c_str(); printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown memory operand type for %s\n", name ); @@ -147,6 +149,8 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in result.u64 = op.get_symbol()->get_address(); } else if ( op.is_shared() ) { result.u64 = op.get_symbol()->get_address(); + } else if ( op.is_sstarr() ) { + result.u64 = op.get_symbol()->get_address(); } else if ( op.is_const() ) { result.u64 = op.get_symbol()->get_address(); } else if ( op.is_global() ) { @@ -1459,6 +1463,157 @@ void breakaddr_impl( const ptx_instruction *pI, ptx_thread_info *thread ) void brev_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } void brkpt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } +unsigned trunc(unsigned num, unsigned precision) { + int mask = 1, latest_one = -1; + unsigned data = num; + for (unsigned j = 0; j < sizeof(unsigned)*8; j++) { + int bit = data & mask; + if (bit == 1) latest_one = j; + data >>= 1; + } + if (latest_one >= precision) { + // round_up is 1 if the most significant truncated digit is a 1, otherwise it is 0 + //int round_up = (num & (1 << (latest_one-precision))) >> (latest_one-precision); + //unsigned shifted_output = num >> (latest_one-precision+1); + // if shifted_output is a number like 1111, don't round up + //if (shifted_output == (pow(2,precision)-1)) round_up = 0; + //num = shifted_output + round_up; + num >>= (latest_one-precision+1); + } + return num; +} + +void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) +{ + // operands: + // 0 = output + // 1 = input precision + // 2 = output precision + // 3 = buffer0 + // 4 = buffer1 + // 5 = buffer2 + // 6 = buffer3 + // 7 = synapse value + // 8 = output value + + const operand_info &dst = pI->dst(); + const operand_info &src1 = pI->src1(); + const operand_info &src2 = pI->src2(); + unsigned type = pI->get_type(); + int tid = inst.warp_id() * core->get_warp_size(); + ptx_thread_info *thread = core->get_thread_info()[tid]; + const int ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32; + const int op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32; + const int THREADS = inst.active_count(); + const int INBUFFERS = 4; + const int OUTBUFFERS = (((32/ip)*INBUFFERS) / (32/op)) + ((((32/ip)*INBUFFERS) % (32/op)) != 0); + if (OUTBUFFERS > THREADS) { + printf("GPGPU-Sim PTX: BSMAD ERROR - Number of output registers required (%d) is greater than the number available (%d)\n", OUTBUFFERS, THREADS); + abort(); + } + ptx_warp_info *warp_info = thread->m_warp_info; + warp_info->inc_done_threads(); + + // threads within the warp are executed sequentially by the simulator, store output in first four registers + if (warp_info->get_done_threads() <= OUTBUFFERS) { + unsigned buffer[THREADS][INBUFFERS]; + unsigned synapse[THREADS]; + unsigned output; + + // loop through all threads in the warp and get all data + for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) { + if (inst.active(i)) { + const operand_info &src3 = pI->operand_lookup(3); + const operand_info &src4 = pI->operand_lookup(4); + const operand_info &src5 = pI->operand_lookup(5); + const operand_info &src6 = pI->operand_lookup(6); + const operand_info &src7 = pI->operand_lookup(7); + const operand_info &src8 = pI->operand_lookup(8); + + thread = core->get_thread_info()[tid+i]; + // get buffer data and synapse data from each thread + buffer[j][0] = (thread->get_operand_value(src3, dst, type, thread, 1)).u32; + buffer[j][1] = (thread->get_operand_value(src4, dst, type, thread, 1)).u32; + buffer[j][2] = (thread->get_operand_value(src5, dst, type, thread, 1)).u32; + buffer[j][3] = (thread->get_operand_value(src6, dst, type, thread, 1)).u32; + synapse[j] = (thread->get_operand_value(src7, dst, type, thread, 1)).u32; + j++; + // get output data from the first 4 threads + if (j == warp_info->get_done_threads()) { + output = (thread->get_operand_value(src8, dst, type, thread, 1)).u32; + } + } + } + + // unpack registers, compute enough outputs to fill an output register + unsigned *unpacked_output = (unsigned*)calloc(32/op,sizeof(unsigned)); + unsigned buffer_data_start = (32/op)*(warp_info->get_done_threads()-1); + for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*INBUFFERS; i++) { + unsigned buf = i/(32/ip); + unsigned pos = i%(32/ip); + // sum values from the buffers + int sum = 0; + unsigned mask = (unsigned)(pow(2,ip)-1) << (pos*ip); + for (int j = 0; j < THREADS; j++) { + //sum += ((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j]; + sum += trunc(((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j], op); + } + // get the previous output + mask = (unsigned)(pow(2,op)-1) << (op*(i-buffer_data_start)); + int past_output = (mask & output) >> (op*(i-buffer_data_start)); + unpacked_output[i-buffer_data_start] = trunc(trunc(sum,op) + past_output,op); + // truncate sum, truncate (truncated sum + past_output) + } + + // truncate output + /*for (unsigned i = 0; i < 32/op; i++) { + int mask = 1, latest_one = -1; + unsigned data = unpacked_output[i]; + for (unsigned j = 0; j < sizeof(unsigned)*8; j++) { + int bit = data & mask; + if (bit == 1) latest_one = j; + data >>= 1; + } + if (latest_one >= op) { + // round_up is 1 if the most significant truncated digit is a 1, otherwise it is 0 + int round_up = (unpacked_output[i] & (1 << (latest_one-op))) >> (latest_one-op); + unsigned shifted_output = unpacked_output[i] >> (latest_one-op+1); + // if shifted_output is a number like 1111, don't round up + if (shifted_output == (pow(2,op)-1)) round_up = 0; + unpacked_output[i] = shifted_output + round_up; + } + }*/ + + // pack the outputs into one register + unsigned mask = pow(2,op)-1; + unsigned output_data = 0; + for (int i = 0; i < 32/op; i++) { + output_data |= (unpacked_output[i] & mask) << (op*i); + } + + // store the result in the correct thread's output register + for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) { + if (inst.active(i)) j++; + if (j == warp_info->get_done_threads()) { + thread = core->get_thread_info()[tid+i]; + ptx_reg_t data; + data.u32 = output_data; + thread->set_operand_value(dst, data, type, thread, pI); + break; + } + } + } + + // once the warp has finished, set the number of completed threads back to 0 for the next warp + if (warp_info->get_done_threads() == THREADS) { + warp_info->reset_done_threads(); + } + + // set the latency assuming 4 bits of each input get processed every cycle + // mutable latency variable??? + //pI->latency = (ip+3)/4; +} + void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { static unsigned call_uid_next = 1; @@ -2370,6 +2525,7 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand case surf_space: mem = thread->get_surf_memory(); break; case param_space_kernel: mem = thread->get_param_memory(); break; case shared_space: mem = thread->m_shared_mem; break; + case sstarr_space: mem = thread->m_sstarr_mem; break; case const_space: mem = thread->get_global_memory(); break; case generic_space: if( thread->get_ptx_version().ver() >= 2.0 ) { @@ -3832,6 +3988,88 @@ void sqrt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->set_operand_value(dst,d, i_type, thread, pI); } +void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) +{ + ptx_instruction * cpI = const_cast<ptx_instruction *>(pI); // constant + const operand_info &dst = cpI->dst(); + const operand_info &src1 = pI->src1(); + const operand_info &src2 = pI->src2(); + const operand_info &src3 = pI->src3(); + unsigned type = pI->get_type(); + ptx_reg_t dst_data = thread->get_operand_value(dst, dst, type, thread, 1); + ptx_reg_t src1_data = thread->get_operand_value(src1, src1, type, thread, 1); + ptx_reg_t src2_data = thread->get_operand_value(src2, src1, type, thread, 1); + ptx_reg_t src3_data = thread->get_operand_value(src3, src1, type, thread, 1); + memory_space_t space = pI->get_space(); + memory_space *mem = NULL; + addr_t addr = src2_data.u32 * 4; // this assumes sstarr memory starts at address 0 + ptx_cta_info *cta_info = thread->m_cta_info; + + decode_space(space,thread,src1,mem,addr); + + size_t size; + int t; + type_info_key::type_decode(type,size,t); + + // store data in sstarr memory + mem->write(addr,size/8,&src3_data.s64,thread,pI); + + // sync threads + cpI->set_bar_id(16); // use 16 for sst because bar uses an int from 0-15 + + thread->m_last_effective_address = addr; + thread->m_last_memory_space = space; + thread->m_last_dram_callback.function = bar_callback; + thread->m_last_dram_callback.instruction = cpI; + + // the last thread that executes loads all of the data back from sstarr memory + int NUM_THREADS = cta_info->num_threads(); + cta_info->inc_bar_threads(); + if (NUM_THREADS == cta_info->get_bar_threads()) { + unsigned offset = 0; + addr = 0; + ptx_reg_t data; + float sstarr_fdata[NUM_THREADS]; + signed long long sstarr_ldata[NUM_THREADS]; + // loop through all of the threads + for (int tid = 0; tid < NUM_THREADS; tid++) { + data.u64=0; + mem->read(addr+(tid*4),size/8,&data.s64); + sstarr_fdata[tid] = data.f32; + sstarr_ldata[tid] = data.s64; + } + + // squeeze the zeros out of the array and store data back into original array + mem = NULL; + addr = src1_data.u32; + space.set_type(global_space); + decode_space(space,thread,src1,mem,addr); + // store nonzero entries and indices + for (int tid = 0; tid < NUM_THREADS; tid++) { + if (sstarr_fdata[tid] != 0) { + float ftid = (float)tid; + mem->write(addr+(offset*4),size/8,&sstarr_ldata[tid],thread,pI); + mem->write(addr+((NUM_THREADS+offset)*4),size/8,&ftid,thread,pI); + offset++; + } + } + // store the number of nonzero elements in the array + data = thread->get_operand_value(src1, dst, type, thread, 1); + data.s64 += 4*(offset-1); + thread->set_operand_value(dst, data, type, thread, pI); + + // fill the rest of the array with zeros (dst should always have a 0 in it) + while (offset < NUM_THREADS) { + mem->write(addr+(offset*4),size/8,&dst_data.s64,thread,pI); + offset++; + } + + cta_info->reset_bar_threads(); + thread->m_last_effective_address = addr+(NUM_THREADS-1)*4; + thread->m_last_memory_space = space; + } +} + void ssy_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { //printf("Execution Warning: unimplemented ssy instruction is treated as a nop\n"); diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index e1b1422..41f2f22 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -52,6 +52,7 @@ OP_DEF(BRA_OP,bra_impl,"bra",0,3) OP_DEF(BRX_OP,brx_impl,"brx",0,3) OP_DEF(BREV_OP,brev_impl,"brev",1,1) OP_DEF(BRKPT_OP,brkpt_impl,"brkpt",1,9) +OP_W_DEF(BSMAD_OP,bsmad_impl,"bsmad",1,1) OP_DEF(CALL_OP,call_impl,"call",1,3) OP_DEF(CALLP_OP,callp_impl,"callp",1,3) OP_DEF(CLZ_OP,clz_impl,"clz",1,1) @@ -104,6 +105,7 @@ OP_DEF(SHR_OP,shr_impl,"shr",1,1) OP_DEF(SIN_OP,sin_impl,"sin",1,4) OP_DEF(SLCT_OP,slct_impl,"slct",1,1) OP_DEF(SQRT_OP,sqrt_impl,"sqrt",1,4) +OP_DEF(SST_OP,sst_impl,"sst",1,5) OP_DEF(SSY_OP,ssy_impl,"ssy",0,3) OP_DEF(ST_OP,st_impl,"st",0,5) OP_DEF(SUB_OP,sub_impl,"sub",1,1) diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 5471d6f..7620134 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -68,6 +68,7 @@ bra TC; ptx_lval.int_value = BRA_OP; return OPCODE; brx TC; ptx_lval.int_value = BRX_OP; return OPCODE; brev TC; ptx_lval.int_value = BREV_OP; return OPCODE; brkpt TC; ptx_lval.int_value = BRKPT_OP; return OPCODE; +bsmad TC; ptx_lval.int_value = BSMAD_OP; return OPCODE; call TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode callp TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALLP_OP; return OPCODE; clz TC; ptx_lval.int_value = CLZ_OP; return OPCODE; @@ -121,6 +122,7 @@ shr TC; ptx_lval.int_value = SHR_OP; return OPCODE; sin TC; ptx_lval.int_value = SIN_OP; return OPCODE; slct TC; ptx_lval.int_value = SLCT_OP; return OPCODE; sqrt TC; ptx_lval.int_value = SQRT_OP; return OPCODE; +sst TC; ptx_lval.int_value = SST_OP; return OPCODE; ssy TC; ptx_lval.int_value = SSY_OP; return OPCODE; st TC; ptx_lval.int_value = ST_OP; return OPCODE; st.volatile TC; ptx_lval.int_value = ST_OP; return OPCODE; @@ -148,6 +150,8 @@ nop TC; ptx_lval.int_value = NOP_OP; return OPCODE; break TC; ptx_lval.int_value = BREAK_OP; return OPCODE; breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; +"CPTX_END" printf("ENDING CUSTOM PTX.\n"); BEGIN(IN_COMMENT); + <INITIAL,NOT_OPCODE,IN_INST,IN_FUNC_DECL>{ \.align TC; return ALIGN_DIRECTIVE; @@ -175,6 +179,7 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; \.section TC; return SECTION_DIRECTIVE; \.shared TC; return SHARED_DIRECTIVE; \.sreg TC; return SREG_DIRECTIVE; +\.sstarr TC; return SSTARR_DIRECTIVE; \.struct TC; return STRUCT_DIRECTIVE; \.surf TC; return SURF_DIRECTIVE; /* not in PTX 2.1 */ \.target TC; return TARGET_DIRECTIVE; @@ -399,9 +404,9 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; <IN_COMMENT>{ "*/" BEGIN(INITIAL); "CPTX_BEGIN" printf("BEGINNING CUSTOM PTX.\n"); BEGIN(INITIAL); -[^C*\n]+ // eat comment in chunks -"C" -"*" // eat the lone star +[^C*\n]+ // eat comment in chunks +"C" // eat the lone C +"*" // eat the lone star \n TC; } diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y index e00aa4b..3360c55 100644 --- a/src/cuda-sim/ptx.y +++ b/src/cuda-sim/ptx.y @@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %token SECTION_DIRECTIVE %token SHARED_DIRECTIVE %token SREG_DIRECTIVE +%token SSTARR_DIRECTIVE %token STRUCT_DIRECTIVE %token SURF_DIRECTIVE %token TARGET_DIRECTIVE @@ -347,6 +348,7 @@ addressable_spec: CONST_DIRECTIVE { add_space_spec(const_space,$1); } | LOCAL_DIRECTIVE { add_space_spec(local_space,0); } | PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); } | SHARED_DIRECTIVE { add_space_spec(shared_space,0); } + | SSTARR_DIRECTIVE { add_space_spec(sstarr_space,0); } | SURF_DIRECTIVE { add_space_spec(surf_space,0); } | TEX_DIRECTIVE { add_space_spec(tex_space,0); } ; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 9ad1571..4c10373 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -222,6 +222,7 @@ public: bool is_label() const { return m_is_label;} bool is_shared() const { return m_is_shared;} + bool is_sstarr() const { return m_is_sstarr;} bool is_const() const { return m_is_const;} bool is_global() const { return m_is_global;} bool is_local() const { return m_is_local;} @@ -279,6 +280,7 @@ private: bool m_address_valid; bool m_is_label; bool m_is_shared; + bool m_is_sstarr; bool m_is_const; bool m_is_global; bool m_is_local; @@ -314,10 +316,12 @@ public: void set_label_address( const symbol *label, unsigned addr ); unsigned next_reg_num() { return ++m_reg_allocator;} addr_t get_shared_next() { return m_shared_next;} + addr_t get_sstarr_next() { return m_sstarr_next;} addr_t get_global_next() { return m_global_next;} addr_t get_local_next() { return m_local_next;} addr_t get_tex_next() { return m_tex_next;} void alloc_shared( unsigned num_bytes ) { m_shared_next += num_bytes;} + void alloc_sstarr( unsigned num_bytes ) { m_sstarr_next += num_bytes;} void alloc_global( unsigned num_bytes ) { m_global_next += num_bytes;} void alloc_local( unsigned num_bytes ) { m_local_next += num_bytes;} void alloc_tex( unsigned num_bytes ) { m_tex_next += num_bytes;} @@ -339,6 +343,7 @@ public: private: unsigned m_reg_allocator; unsigned m_shared_next; + unsigned m_sstarr_next; unsigned m_const_next; unsigned m_global_next; unsigned m_local_next; @@ -713,6 +718,7 @@ public: } return m_value.m_symbolic->is_shared(); } + bool is_sstarr() const { return m_value.m_symbolic->is_sstarr();} bool is_const() const { return m_value.m_symbolic->is_const();} bool is_global() const { return m_value.m_symbolic->is_global();} bool is_local() const { return m_value.m_symbolic->is_local();} diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index baa3bcd..7fc54e9 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -440,6 +440,20 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident g_last_symbol->set_address( addr+addr_pad ); g_current_symbol_table->alloc_shared( num_bits/8 + addr_pad ); break; + case sstarr_space: + printf("GPGPU-Sim PTX: allocating sstarr region for \"%s\" ", + identifier); + fflush(stdout); + assert( (num_bits%8) == 0 ); + addr = g_current_symbol_table->get_sstarr_next(); + addr_pad = pad_address(addr, num_bits/8, 128); + printf("from 0x%x to 0x%lx (sstarr memory space)\n", + addr+addr_pad, + addr+addr_pad + num_bits/8); + fflush(stdout); + g_last_symbol->set_address( addr+addr_pad ); + g_current_symbol_table->alloc_sstarr( num_bits/8 + addr_pad ); + break; case const_space: if( array_ident == ARRAY_IDENTIFIER_NO_DIM ) { printf("GPGPU-Sim PTX: deferring allocation of constant region for \"%s\" (need size information)\n", identifier ); diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index a3e43aa..820287d 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -44,6 +44,7 @@ ptx_cta_info::ptx_cta_info( unsigned sm_idx ) m_sm_idx = sm_idx; m_uid = g_ptx_cta_info_uid++; + m_bar_threads = 0; } void ptx_cta_info::add_thread( ptx_thread_info *thd ) @@ -128,6 +129,21 @@ unsigned ptx_cta_info::get_sm_idx() const return m_sm_idx; } +unsigned ptx_cta_info::get_bar_threads() const +{ + return m_bar_threads; +} + +void ptx_cta_info::inc_bar_threads() +{ + m_bar_threads++; +} + +void ptx_cta_info::reset_bar_threads() +{ + m_bar_threads = 0; +} + ptx_warp_info::ptx_warp_info() { reset_done_threads(); @@ -173,6 +189,7 @@ ptx_thread_info::ptx_thread_info( kernel_info_t &kernel ) m_last_memory_space = undefined_space; m_branch_taken = 0; m_shared_mem = NULL; + m_sstarr_mem = NULL; m_warp_info = NULL; m_cta_info = NULL; m_local_mem = NULL; diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index e6eb02e..05acf20 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -158,8 +158,12 @@ public: void register_thread_exit( ptx_thread_info *thd ); void register_deleted_thread( ptx_thread_info *thd ); unsigned get_sm_idx() const; + unsigned get_bar_threads() const; + void inc_bar_threads(); + void reset_bar_threads(); private: + unsigned m_bar_threads; unsigned long long m_uid; unsigned m_sm_idx; std::set<ptx_thread_info*> m_threads_in_cta; @@ -169,7 +173,7 @@ private: class ptx_warp_info { public: - ptx_warp_info(); + ptx_warp_info(); // add get_core or something, or threads? unsigned get_done_threads() const; void inc_done_threads(); void reset_done_threads(); @@ -438,6 +442,7 @@ public: memory_space_t m_last_memory_space; dram_callback_t m_last_dram_callback; memory_space *m_shared_mem; + memory_space *m_sstarr_mem; memory_space *m_local_mem; ptx_warp_info *m_warp_info; ptx_cta_info *m_cta_info; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 58a5d16..3bd1892 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1081,6 +1081,9 @@ void shader_core_ctx::mem_instruction_stats(const warp_inst_t &inst) case shared_space: m_stats->gpgpu_n_shmem_insn += active_count; break; + case sstarr_space: + m_stats->gpgpu_n_sstarr_insn += active_count; + break; case const_space: m_stats->gpgpu_n_const_insn += active_count; break; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index d17e51d..92cdb5b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -403,6 +403,7 @@ void shader_core_stats::print( FILE* fout ) const fprintf(fout, "gpgpu_n_load_insn = %d\n", gpgpu_n_load_insn); fprintf(fout, "gpgpu_n_store_insn = %d\n", gpgpu_n_store_insn); fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_shmem_insn); + fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_sstarr_insn); fprintf(fout, "gpgpu_n_tex_insn = %d\n", gpgpu_n_tex_insn); fprintf(fout, "gpgpu_n_const_mem_insn = %d\n", gpgpu_n_const_insn); fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", gpgpu_n_param_insn); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index bdd8dbe..db2af01 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1388,6 +1388,7 @@ struct shader_core_stats_pod { unsigned gpgpu_n_load_insn; unsigned gpgpu_n_store_insn; unsigned gpgpu_n_shmem_insn; + unsigned gpgpu_n_sstarr_insn; unsigned gpgpu_n_tex_insn; unsigned gpgpu_n_const_insn; unsigned gpgpu_n_param_insn; |
