diff options
| author | Inderpreet Singh <[email protected]> | 2011-12-26 00:07:19 -0800 |
|---|---|---|
| committer | Andrew Boktor <[email protected]> | 2014-08-14 13:19:01 -0700 |
| commit | 20b3ca2e081e9ee076483ca06e382002709b54dd (patch) | |
| tree | 0a23508d0d20a17457479f44b969e88a0e0a8474 /src | |
| parent | b916cd600d109938a1621345bfc3c46da4bff4c6 (diff) | |
Fix for Bug 124 - ld.local.s8 instructions are not supported
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 11231]
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.cc | 16 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 34 |
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; } ///////////////////////////////////////////////////////////////////////////////////////// |
