diff options
Diffstat (limited to 'src/cuda-sim/memory.cc')
| -rw-r--r-- | src/cuda-sim/memory.cc | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/src/cuda-sim/memory.cc b/src/cuda-sim/memory.cc index b825f12..aecfd31 100644 --- a/src/cuda-sim/memory.cc +++ b/src/cuda-sim/memory.cc @@ -83,10 +83,35 @@ template<unsigned BSIZE> memory_space_impl<BSIZE>::memory_space_impl( std::strin template<unsigned BSIZE> void memory_space_impl<BSIZE>::write( mem_addr_t addr, size_t length, const void *data, class ptx_thread_info *thd, const ptx_instruction *pI) { mem_addr_t index = addr >> m_log2_block_size; - unsigned offset = addr & (BSIZE-1); - unsigned nbytes = length; - assert( (addr+length) <= (index+1)*BSIZE ); - m_data[index].write(offset,nbytes,(const unsigned char*)data); + if ( (addr+length) <= (index+1)*BSIZE ) { + // fast route for intra-block access + unsigned offset = addr & (BSIZE-1); + unsigned nbytes = length; + m_data[index].write(offset,nbytes,(const unsigned char*)data); + } else { + // slow route for inter-block access + unsigned nbytes_remain = length; + unsigned src_offset = 0; + mem_addr_t current_addr = addr; + + while (nbytes_remain > 0) { + unsigned offset = current_addr & (BSIZE-1); + mem_addr_t page = current_addr >> m_log2_block_size; + mem_addr_t access_limit = offset + nbytes_remain; + if (access_limit > BSIZE) { + access_limit = BSIZE; + } + + size_t tx_bytes = access_limit - offset; + m_data[page].write(offset, tx_bytes, &((const unsigned char*)data)[src_offset]); + + // advance pointers + src_offset += tx_bytes; + current_addr += tx_bytes; + nbytes_remain -= tx_bytes; + } + assert(nbytes_remain == 0); + } if( !m_watchpoints.empty() ) { std::map<unsigned,mem_addr_t>::iterator i; for( i=m_watchpoints.begin(); i!=m_watchpoints.end(); i++ ) { @@ -97,28 +122,59 @@ template<unsigned BSIZE> void memory_space_impl<BSIZE>::write( mem_addr_t addr, } } -template<unsigned BSIZE> void memory_space_impl<BSIZE>::read( mem_addr_t addr, size_t length, void *data ) const +template<unsigned BSIZE> void memory_space_impl<BSIZE>::read_single_block( mem_addr_t blk_idx, mem_addr_t addr, size_t length, void *data) const { - mem_addr_t index = addr >> m_log2_block_size; - unsigned offset = addr & (BSIZE-1); - unsigned nbytes = length; - typename map_t::const_iterator i = m_data.find(index); - if( (addr+length) > (index+1)*BSIZE ) { + if ((addr + length) > (blk_idx + 1) * BSIZE) { printf("GPGPU-Sim PTX: ERROR * access to memory \'%s\' is unaligned : addr=0x%x, length=%zu\n", m_name.c_str(), addr, length); printf("GPGPU-Sim PTX: (addr+length)=0x%lx > 0x%x=(index+1)*BSIZE, index=0x%x, BSIZE=0x%x\n", - (addr+length),(index+1)*BSIZE, index, BSIZE); + (addr+length),(blk_idx+1)*BSIZE, blk_idx, BSIZE); throw 1; } + typename map_t::const_iterator i = m_data.find(blk_idx); if( i == m_data.end() ) { for( size_t n=0; n < length; n++ ) ((unsigned char*)data)[n] = (unsigned char) 0; //printf("GPGPU-Sim PTX: WARNING reading %zu bytes from unititialized memory at address 0x%x in space %s\n", length, addr, m_name.c_str() ); } else { + unsigned offset = addr & (BSIZE-1); + unsigned nbytes = length; i->second.read(offset,nbytes,(unsigned char*)data); } } +template<unsigned BSIZE> void memory_space_impl<BSIZE>::read( mem_addr_t addr, size_t length, void *data ) const +{ + mem_addr_t index = addr >> m_log2_block_size; + if ((addr+length) <= (index+1)*BSIZE ) { + // fast route for intra-block access + read_single_block(index, addr, length, data); + } else { + // slow route for inter-block access + unsigned nbytes_remain = length; + unsigned dst_offset = 0; + mem_addr_t current_addr = addr; + + while (nbytes_remain > 0) { + unsigned offset = current_addr & (BSIZE-1); + mem_addr_t page = current_addr >> m_log2_block_size; + mem_addr_t access_limit = offset + nbytes_remain; + if (access_limit > BSIZE) { + access_limit = BSIZE; + } + + size_t tx_bytes = access_limit - offset; + read_single_block(page, current_addr, tx_bytes, &((unsigned char*)data)[dst_offset]); + + // advance pointers + dst_offset += tx_bytes; + current_addr += tx_bytes; + nbytes_remain -= tx_bytes; + } + assert(nbytes_remain == 0); + } +} + template<unsigned BSIZE> void memory_space_impl<BSIZE>::print( const char *format, FILE *fout ) const { typename map_t::const_iterator i_page; |
