diff options
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 59 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 31 |
2 files changed, 85 insertions, 5 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index e1e41a5..0602e20 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -219,9 +219,16 @@ enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, m } else if ( line->get_status(mask) == VALID ) { idx = index; return HIT; - } else if ( line->get_status(mask) == MODIFIED ) { - idx = index; - return HIT; + } else if ( line->get_status(mask) == MODIFIED) { + if(line->is_readable(mask)) { + idx = index; + return HIT; + } + else { + idx = index; + return SECTOR_MISS; + } + } else if ( line->is_valid_line() && line->get_status(mask) == INVALID ) { idx = index; return SECTOR_MISS; @@ -1125,6 +1132,50 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, { new_addr_type block_addr = m_config.block_addr(addr); + new_addr_type mshr_addr = m_config.mshr_addr(mf->get_addr()); + + + //if the request writes to the whole cache line/sector, then, write and set cache line Modified. + //and no need to send read request to memory or reserve mshr + + if(miss_queue_full(0)) { + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + return RESERVATION_FAIL; // cannot handle request this cycle + } + + bool wb = false; + evicted_block_info evicted; + + cache_request_status m_status = m_tag_array->access(block_addr,time,cache_index,wb,evicted,mf); + assert(m_status != HIT); + cache_block_t* block = m_tag_array->get_block(cache_index); + block->set_status(MODIFIED, mf->get_access_sector_mask()); + if(m_status == HIT_RESERVED) { + block->set_ignore_on_fill(true, mf->get_access_sector_mask()); + block->set_modified_on_fill(true, mf->get_access_sector_mask()); + } + + if(mf->get_access_byte_mask().count() == m_config.get_atom_sz()) + { + block->set_m_readable(true, mf->get_access_sector_mask()); + } else + { + block->set_m_readable(false, mf->get_access_sector_mask()); + } + + if( m_status != RESERVATION_FAIL ){ + // If evicted block is modified and not a write-through + // (already modified lower level) + if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { + mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, + m_wrbk_type,evicted.m_modified_size,true); + send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); + } + return MISS; + } + return RESERVATION_FAIL; + + /*new_addr_type block_addr = m_config.block_addr(addr); new_addr_type mshr_addr = m_config.mshr_addr(mf->get_addr()); if(mf->get_access_byte_mask().count() == m_config.get_atom_sz()) @@ -1233,7 +1284,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, return MISS; } return RESERVATION_FAIL; - } + }*/ } /// No write-allocate miss: Simply send write request to lower level memory diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 6a84a3a..0d07878 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -123,8 +123,11 @@ struct cache_block_t { virtual void set_ignore_on_fill(bool m_ignore, mem_access_sector_mask_t sector_mask) = 0; virtual void set_modified_on_fill(bool m_modified, mem_access_sector_mask_t sector_mask) = 0; virtual unsigned get_modified_size() = 0; + virtual void set_m_readable(bool readable, mem_access_sector_mask_t sector_mask)=0; + virtual bool is_readable(mem_access_sector_mask_t sector_mask)=0; virtual ~cache_block_t() {} + new_addr_type m_tag; new_addr_type m_block_addr; @@ -139,6 +142,7 @@ struct line_cache_block: public cache_block_t { m_status=INVALID; m_ignore_on_fill_status = false; m_set_modified_on_fill = false; + m_readable = true; } void allocate( new_addr_type tag, new_addr_type block_addr, unsigned time, mem_access_sector_mask_t sector_mask ) { @@ -209,6 +213,13 @@ struct line_cache_block: public cache_block_t { { return SECTOR_CHUNCK_SIZE * SECTOR_SIZE; //i.e. cache line size } + virtual void set_m_readable(bool readable, mem_access_sector_mask_t sector_mask) + { + m_readable = readable; + } + virtual bool is_readable(mem_access_sector_mask_t sector_mask) { + return m_readable; + } private: @@ -218,6 +229,7 @@ private: cache_block_state m_status; bool m_ignore_on_fill_status; bool m_set_modified_on_fill; + bool m_readable; }; struct sector_cache_block : public cache_block_t { @@ -234,6 +246,7 @@ struct sector_cache_block : public cache_block_t { m_status[i]= INVALID; m_ignore_on_fill_status[i] = false; m_set_modified_on_fill[i] = false; + m_readable[i] = true; } m_line_alloc_time=0; m_line_last_access_time=0; @@ -279,9 +292,15 @@ struct sector_cache_block : public cache_block_t { m_sector_alloc_time[sidx]=time; m_last_sector_access_time[sidx]=time; m_sector_fill_time[sidx]=0; + if(m_status[sidx]==MODIFIED) //this should be the case only for fetch-on-write policy //TO DO + m_set_modified_on_fill[sidx] = true; + else + m_set_modified_on_fill[sidx] = false; + m_status[sidx]=RESERVED; m_ignore_on_fill_status[sidx] = false; - m_set_modified_on_fill[sidx] = false; + //m_set_modified_on_fill[sidx] = false; + m_readable[sidx] = true; //set line stats m_line_last_access_time=time; @@ -362,6 +381,15 @@ struct sector_cache_block : public cache_block_t { unsigned sidx = get_sector_index(sector_mask); m_set_modified_on_fill[sidx] = m_modified; } + virtual void set_m_readable(bool readable, mem_access_sector_mask_t sector_mask) + { + unsigned sidx = get_sector_index(sector_mask); + m_readable[sidx] = readable; + } + virtual bool is_readable(mem_access_sector_mask_t sector_mask) { + unsigned sidx = get_sector_index(sector_mask); + return m_readable[sidx]; + } virtual unsigned get_modified_size() { @@ -383,6 +411,7 @@ private: cache_block_state m_status[SECTOR_CHUNCK_SIZE]; bool m_ignore_on_fill_status[SECTOR_CHUNCK_SIZE]; bool m_set_modified_on_fill[SECTOR_CHUNCK_SIZE]; + bool m_readable[SECTOR_CHUNCK_SIZE]; unsigned get_sector_index(mem_access_sector_mask_t sector_mask) { |
