diff options
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 44 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 18 |
2 files changed, 54 insertions, 8 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index fdcbdaf..35a5e3a 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -225,14 +225,31 @@ void tag_array::init( int core_id, int type_id ) is_used = false; } +void tag_array::add_pending_line(mem_fetch *mf){ + assert(mf); + new_addr_type addr = m_config.block_addr(mf->get_addr()); + line_table::const_iterator i = pending_lines.find(addr); + if ( i == pending_lines.end() ) { + pending_lines[addr] = mf->get_inst().get_uid(); + } +} + +void tag_array::remove_pending_line(mem_fetch *mf){ + assert(mf); + new_addr_type addr = m_config.block_addr(mf->get_addr()); + line_table::const_iterator i = pending_lines.find(addr); + if ( i != pending_lines.end() ) { + pending_lines.erase(addr); + } +} -enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, mem_fetch* mf) const { +enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, mem_fetch* mf, bool probe_mode) const { mem_access_sector_mask_t mask = mf->get_access_sector_mask(); - return probe(addr, idx, mask); + return probe(addr, idx, mask, probe_mode, mf); } -enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, mem_access_sector_mask_t mask) const { +enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, mem_access_sector_mask_t mask, bool probe_mode, mem_fetch* mf) const { //assert( m_config.m_write_policy == READ_ONLY ); unsigned set_index = m_config.set_index(addr); new_addr_type tag = m_config.tag(addr); @@ -302,6 +319,16 @@ enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, m idx = valid_line; } else abort(); // if an unreserved block exists, it is either invalid or replaceable + + if(probe_mode && m_config.is_streaming()){ + line_table::const_iterator i = pending_lines.find(m_config.block_addr(addr)); + assert(mf); + if ( !mf->is_write() && i != pending_lines.end() ) { + if(i->second != mf->get_inst().get_uid()) + return SECTOR_MISS; + } + } + return MISS; } @@ -951,8 +978,11 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time){ mf->set_addr( e->second.m_addr ); if ( m_config.m_alloc_policy == ON_MISS ) m_tag_array->fill(e->second.m_cache_index,time,mf); - else if ( m_config.m_alloc_policy == ON_FILL ) + else if ( m_config.m_alloc_policy == ON_FILL ) { m_tag_array->fill(e->second.m_block_addr,time,mf); + if(m_config.is_streaming()) + m_tag_array->remove_pending_line(mf); + } else abort(); bool has_atomic = false; m_mshrs.mark_ready(e->second.m_block_addr, has_atomic); @@ -1006,6 +1036,7 @@ void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_a m_mshrs.add(mshr_addr,mf); do_miss = true; + } else if ( !mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size) ) { if(read_only) m_tag_array->access(block_addr,time,cache_index,mf); @@ -1013,6 +1044,9 @@ void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_a m_tag_array->access(block_addr,time,cache_index,wb,evicted,mf); m_mshrs.add(mshr_addr,mf); + if(m_config.is_streaming() && m_config.m_cache_type == SECTOR){ + m_tag_array->add_pending_line(mf); + } m_extra_mf_fields[mf] = extra_mf_fields(mshr_addr,mf->get_addr(),cache_index, mf->get_data_size(), m_config); mf->set_data_size( m_config.get_atom_sz() ); mf->set_addr( mshr_addr ); @@ -1536,7 +1570,7 @@ data_cache::access( new_addr_type addr, new_addr_type block_addr = m_config.block_addr(addr); unsigned cache_index = (unsigned)-1; enum cache_request_status probe_status - = m_tag_array->probe( block_addr, cache_index, mf ); + = m_tag_array->probe( block_addr, cache_index, mf, true); enum cache_request_status access_status = process_tag_probe( wr, probe_status, addr, cache_index, mf, time, events ); m_stats.inc_stats(mf->get_access_type(), diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index d1cba78..e663cf6 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -506,6 +506,7 @@ public: m_config_stringPrefShared = NULL; m_data_port_width = 0; m_set_index_function = LINEAR_SET_FUNCTION; + m_is_streaming = false; } void init(char * config, FuncCache status) { @@ -565,7 +566,7 @@ public: //For more information about streaming cache, see: // http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf // https://ieeexplore.ieee.org/document/8344474/ - + m_is_streaming = true; m_alloc_policy = ON_FILL; m_mshr_entries = m_nset*m_assoc*MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; if(m_cache_type == SECTOR) @@ -709,6 +710,9 @@ public: assert( m_valid ); return (m_assoc*m_nset*m_line_sz)/1024; } + bool is_streaming() { + return m_is_streaming; + } FuncCache get_cache_status() {return cache_status;} char *m_config_string; char *m_config_stringPrefL1; @@ -731,6 +735,7 @@ protected: unsigned m_assoc; unsigned m_atom_sz; unsigned original_m_assoc; + bool m_is_streaming; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO enum write_policy_t m_write_policy; // 'T' = write through, 'B' = write back, 'R' = read only @@ -789,8 +794,8 @@ public: tag_array(cache_config &config, int core_id, int type_id ); ~tag_array(); - enum cache_request_status probe( new_addr_type addr, unsigned &idx, mem_fetch* mf ) const; - enum cache_request_status probe( new_addr_type addr, unsigned &idx, mem_access_sector_mask_t mask ) const; + enum cache_request_status probe( new_addr_type addr, unsigned &idx, mem_fetch* mf, bool probe_mode=false ) const; + enum cache_request_status probe( new_addr_type addr, unsigned &idx, mem_access_sector_mask_t mask, bool probe_mode=false, mem_fetch* mf = NULL ) const; enum cache_request_status access( new_addr_type addr, unsigned time, unsigned &idx, mem_fetch* mf ); enum cache_request_status access( new_addr_type addr, unsigned time, unsigned &idx, bool &wb, evicted_block_info &evicted, mem_fetch* mf ); @@ -810,6 +815,8 @@ public: void get_stats(unsigned &total_access, unsigned &total_misses, unsigned &total_hit_res, unsigned &total_res_fail) const; void update_cache_parameters(cache_config &config); + void add_pending_line(mem_fetch *mf); + void remove_pending_line(mem_fetch *mf); protected: // This constructor is intended for use only from derived classes that wish to // avoid unnecessary memory allocation that takes place in the @@ -841,6 +848,9 @@ protected: int m_type_id; // what kind of cache is this (normal, texture, constant) bool is_used; //a flag if the whole cache has ever been accessed before + + typedef tr1_hash_map<new_addr_type,unsigned> line_table; + line_table pending_lines; }; class mshr_table { @@ -890,7 +900,9 @@ private: mshr_entry() : m_has_atomic(false) { } }; typedef tr1_hash_map<new_addr_type,mshr_entry> table; + typedef tr1_hash_map<new_addr_type,mshr_entry> line_table; table m_data; + line_table pending_lines; // it may take several cycles to process the merged requests bool m_current_response_ready; |
