diff options
| -rw-r--r-- | src/abstract_hardware_model.cc | 33 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 18 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 31 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 4 |
4 files changed, 60 insertions, 26 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index e883455..1cce2f2 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -123,7 +123,7 @@ void warp_inst_t::generate_mem_accesses() for( unsigned thread=subwarp*subwarp_size; thread < (subwarp+1)*subwarp_size; thread++ ) { if( !active(thread) ) continue; - new_addr_type addr = m_per_scalar_thread[thread].memreqaddr; + new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[0]; //FIXME: deferred allocation of shared memory should not accumulate across kernel launches //assert( addr < m_config->gpgpu_shmem_size ); unsigned bank = m_config->shmem_bank_func(addr); @@ -211,15 +211,26 @@ void warp_inst_t::generate_mem_accesses() for( unsigned thread=subwarp*subwarp_size; thread<subwarp_size*(subwarp+1); thread++ ) { if( !active(thread) ) continue; - new_addr_type addr = m_per_scalar_thread[thread].memreqaddr; - unsigned block_address = line_size_based_tag_func(addr,segment_size); - unsigned chunk = (addr&127)/32; // which 32-byte chunk within in a 128-byte chunk does this thread access? - transaction_info &info = subwarp_transactions[block_address]; - info.chunks.set(chunk); - info.active.set(thread); - unsigned idx = (addr&127); - for( unsigned i=0; i < data_size; i++ ) - info.bytes.set(idx+i); + + // local memory can only be accessed in 4B chunks by one thread + unsigned data_size_coales = (space.get_type() == local_space || space.get_type() == param_space_local ) ? 4 : data_size; + unsigned num_accesses = (space.get_type() == local_space || space.get_type() == param_space_local ) ? data_size/4 : 1; + + for(unsigned access=0; access<num_accesses; access++) { + new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[access]; + unsigned block_address = line_size_based_tag_func(addr,segment_size); + unsigned chunk = (addr&127)/32; // which 32-byte chunk within in a 128-byte chunk does this thread access? + transaction_info &info = subwarp_transactions[block_address]; + + // can only write to one segment + assert(block_address == line_size_based_tag_func(addr+data_size_coales-1,segment_size)); + + info.chunks.set(chunk); + info.active.set(thread); + unsigned idx = (addr&127); + for( unsigned i=0; i < data_size_coales; i++ ) + info.bytes.set(idx+i); + } } // step 2: reduce each transaction size, if possible @@ -293,7 +304,7 @@ void warp_inst_t::generate_mem_accesses() for( unsigned thread=0; thread < m_config->warp_size; thread++ ) { if( !active(thread) ) continue; - new_addr_type addr = m_per_scalar_thread[thread].memreqaddr; + new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[0]; unsigned block_address = line_size_based_tag_func(addr,cache_block_size); accesses[block_address].set(thread); unsigned idx = addr-block_address; diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 2332670..bb4545e 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -655,7 +655,16 @@ public: m_per_scalar_thread.resize(m_config->warp_size); m_per_scalar_thread_valid=true; } - m_per_scalar_thread[n].memreqaddr = addr; + m_per_scalar_thread[n].memreqaddr[0] = addr; + } + void set_addr( unsigned n, new_addr_type* addr, unsigned num_addrs ) + { + if( !m_per_scalar_thread_valid ) { + m_per_scalar_thread.resize(m_config->warp_size); + m_per_scalar_thread_valid=true; + } + for(unsigned i=0; i<num_addrs; i++) + m_per_scalar_thread[n].memreqaddr[i] = addr[i]; } void generate_mem_accesses(); void add_callback( unsigned lane_id, @@ -720,7 +729,7 @@ public: new_addr_type get_addr( unsigned n ) const { assert( m_per_scalar_thread_valid ); - return m_per_scalar_thread[n].memreqaddr; + return m_per_scalar_thread[n].memreqaddr[0]; } bool isatomic() const { return m_isatomic; } @@ -754,10 +763,11 @@ protected: struct per_thread_info { per_thread_info() { - memreqaddr=0; + for(unsigned i=0; i<8; i++) + memreqaddr[i] = 0; } dram_callback_t callback; - new_addr_type memreqaddr; // effective address + new_addr_type memreqaddr[8]; // effective address, upto 8 different requests (to support 32B access in 8 chunks of 4B each) }; bool m_per_scalar_thread_valid; std::vector<per_thread_info> m_per_scalar_thread; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 855e1c2..166ba88 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -646,9 +646,13 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) m_thread[tid].m_functional_model_thread_state->ptx_exec_inst(inst,t); if( inst.has_callback(t) ) m_warp[inst.warp_id()].inc_n_atomic(); - if (inst.space.is_local() && (inst.is_load() || inst.is_store())) - inst.set_addr(t, translate_local_memaddr(inst.get_addr(t), tid, - m_config->n_simt_clusters*m_config->n_simt_cores_per_cluster) ); + if (inst.space.is_local() && (inst.is_load() || inst.is_store())) { + new_addr_type localaddrs[8]; + unsigned num_addrs; + num_addrs = translate_local_memaddr(inst.get_addr(t), tid, m_config->n_simt_clusters*m_config->n_simt_cores_per_cluster, + inst.data_size, (new_addr_type*) localaddrs ); + inst.set_addr(t, (new_addr_type*) localaddrs, num_addrs); + } if ( ptx_thread_done(tid) ) { m_warp[inst.warp_id()].set_completed(t); m_warp[inst.warp_id()].ibuffer_flush(); @@ -793,7 +797,8 @@ address_type coalesced_segment(address_type addr, unsigned segment_size_lg2bytes return (addr >> segment_size_lg2bytes); } -address_type shader_core_ctx::translate_local_memaddr( address_type localaddr, unsigned tid, unsigned num_shader ) +// Returns numbers of addresses in translated_addrs, each addr points to a 4B (32-bit) word +unsigned shader_core_ctx::translate_local_memaddr( address_type localaddr, unsigned tid, unsigned num_shader, unsigned datasize, new_addr_type* translated_addrs ) { // During functional execution, each thread sees its own memory space for local memory, but these // need to be mapped to a shared address space for timing simulation. We do that mapping here. @@ -824,10 +829,16 @@ address_type shader_core_ctx::translate_local_memaddr( address_type localaddr, u } assert( thread_base < 4/*word size*/*max_concurrent_threads ); - address_type local_word = localaddr/4; - address_type word_offset = localaddr%4; - address_type linear_address = local_word*max_concurrent_threads + thread_base + word_offset; - return linear_address; + assert(datasize%4 == 0); + assert(datasize >= 4); + assert(datasize <= 32); // max 32B + assert(localaddr%4 == 0); // Required if accessing 4B per request, otherwise access will overflow into next thread's space + for(unsigned i=0; i<datasize/4; i++) { + address_type local_word = localaddr/4 + i; + address_type linear_address = local_word*max_concurrent_threads + thread_base; + translated_addrs[i] = linear_address; + } + return datasize/4; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -914,7 +925,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue( cache_t *cache, war delete mf; } else { assert( status == MISS || status == HIT_RESERVED ); - inst.clear_active( access.get_warp_mask() ); // threads in mf writeback when mf returns + //inst.clear_active( access.get_warp_mask() ); // threads in mf writeback when mf returns inst.accessq_pop_back(); if ( inst.is_load() ) { for ( unsigned r=0; r < 4; r++) @@ -980,7 +991,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea mem_fetch *mf = m_mf_allocator->alloc(inst,access); m_icnt->push(mf); inst.accessq_pop_back(); - inst.clear_active( access.get_warp_mask() ); + //inst.clear_active( access.get_warp_mask() ); if( inst.is_load() ) { for( unsigned r=0; r < 4; r++) if(inst.out[r] > 0) diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 8d6c290..7cb3af7 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1242,7 +1242,9 @@ private: friend class scheduler_unit; //this is needed to use private issue warp. void issue_warp( warp_inst_t *&warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); void func_exec_inst( warp_inst_t &inst ); - address_type translate_local_memaddr(address_type localaddr, unsigned tid, unsigned num_shader ); + + // Returns numbers of addresses in translated_addrs + unsigned translate_local_memaddr( address_type localaddr, unsigned tid, unsigned num_shader, unsigned datasize, new_addr_type* translated_addrs ); void read_operands(); |
