summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/abstract_hardware_model.cc33
-rw-r--r--src/abstract_hardware_model.h18
-rw-r--r--src/gpgpu-sim/shader.cc31
-rw-r--r--src/gpgpu-sim/shader.h4
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();