summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.cc16
-rw-r--r--src/gpgpu-sim/shader.cc34
2 files changed, 38 insertions, 12 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 19c3091..1a06001 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -313,9 +313,19 @@ void warp_inst_t::memory_coalescing_arch_13( bool is_write, mem_access_type acce
if( !active(thread) )
continue;
- // 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;
+ unsigned data_size_coales = data_size;
+ unsigned num_accesses = 1;
+
+ if( space.get_type() == local_space || space.get_type() == param_space_local ) {
+ // Local memory accesses >4B were split into 4B chunks
+ if(data_size >= 4) {
+ data_size_coales = 4;
+ num_accesses = data_size/4;
+ }
+ // Otherwise keep the same data_size for sub-4B access to local memory
+ }
+
+
assert(num_accesses <= MAX_ACCESSES_PER_INSN_PER_THREAD);
for(unsigned access=0; access<num_accesses; access++) {
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 7ef5140..b513edb 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -795,16 +795,32 @@ unsigned shader_core_ctx::translate_local_memaddr( address_type localaddr, unsig
}
assert( thread_base < 4/*word size*/*max_concurrent_threads );
- assert(datasize%4 == 0);
- assert(datasize >= 4);
- assert(datasize/4 <= MAX_ACCESSES_PER_INSN_PER_THREAD); // 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*4 + thread_base + LOCAL_GENERIC_START;
- translated_addrs[i] = linear_address;
+ // If requested datasize > 4B, split into multiple 4B accesses
+ // otherwise do one sub-4 byte memory access
+ unsigned num_accesses = 0;
+
+ if(datasize >= 4) {
+ // >4B access, split into 4B chunks
+ assert(datasize%4 == 0); // Must be a multiple of 4B
+ num_accesses = datasize/4;
+ assert(num_accesses <= MAX_ACCESSES_PER_INSN_PER_THREAD); // max 32B
+ assert(localaddr%4 == 0); // Address must be 4B aligned - required if accessing 4B per request, otherwise access will overflow into next thread's space
+ for(unsigned i=0; i<num_accesses; i++) {
+ address_type local_word = localaddr/4 + i;
+ address_type linear_address = local_word*max_concurrent_threads*4 + thread_base + LOCAL_GENERIC_START;
+ translated_addrs[i] = linear_address;
+ }
+ } else {
+ // Sub-4B access, do only one access
+ assert(datasize > 0);
+ num_accesses = 1;
+ address_type local_word = localaddr/4;
+ address_type local_word_offset = localaddr%4;
+ assert( (localaddr+datasize-1)/4 == local_word ); // Make sure access doesn't overflow into next 4B chunk
+ address_type linear_address = local_word*max_concurrent_threads*4 + local_word_offset + thread_base + LOCAL_GENERIC_START;
+ translated_addrs[0] = linear_address;
}
- return datasize/4;
+ return num_accesses;
}
/////////////////////////////////////////////////////////////////////////////////////////