summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gpgpu-sim/gpu-cache.cc59
-rw-r--r--src/gpgpu-sim/gpu-cache.h31
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)
{