diff options
| author | Inderpreet Singh <[email protected]> | 2011-05-25 16:01:16 -0800 |
|---|---|---|
| committer | Inderpreet Singh <[email protected]> | 2011-05-25 16:01:16 -0800 |
| commit | e1cffaf08733754ab55052b6a2729dae57665d29 (patch) | |
| tree | 6bd1fda8aedad981d8295fdf765c85df1e1c8f3d /src/gpgpu-sim | |
| parent | 07376c3d981fbfea6bfad99657c2055b9bdb0e4f (diff) | |
Fix bug #100: local memory address translation returns multiple addresses
Fix bug #101: Coalescing allows multiple accesses per thread for local memory access
This will break atomics which assume at most one thread per mem_fetch. It did not break scoreboard as that logic tracks mem_fetches at warp level, not thread level.
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 9303]
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 31 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 4 |
2 files changed, 24 insertions, 11 deletions
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(); |
