summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorMahmoud <[email protected]>2018-08-22 10:19:52 -0400
committerMahmoud <[email protected]>2018-08-22 10:19:52 -0400
commit8c81c1d04e8d20b08f122a12ce090b4f926adb4c (patch)
tree501c07ab11a733b017fc65fa3e38d636a49ae8a6 /src/gpgpu-sim
parent1e1c08286a505418d0e3ad1ee819e15881e9cb43 (diff)
adding lazy-fetch-on-read and invalidate operation to cache
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc110
-rw-r--r--src/gpgpu-sim/gpu-cache.h22
-rw-r--r--src/gpgpu-sim/gpu-sim.cc6
-rw-r--r--src/gpgpu-sim/l2cache.cc12
-rw-r--r--src/gpgpu-sim/l2cache.h1
-rw-r--r--src/gpgpu-sim/shader.cc16
-rw-r--r--src/gpgpu-sim/shader.h3
7 files changed, 113 insertions, 57 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 75ec00a..9d81de9 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -382,6 +382,8 @@ void tag_array::fill( unsigned index, unsigned time, mem_fetch* mf)
m_lines[index]->fill(time, mf->get_access_sector_mask());
}
+
+//TODO: we need write back the flushed data to the upper level
void tag_array::flush()
{
for (unsigned i=0; i < m_config.get_num_lines(); i++)
@@ -391,6 +393,13 @@ void tag_array::flush()
}
}
+void tag_array::invalidate()
+{
+ for (unsigned i=0; i < m_config.get_num_lines(); i++)
+ for(unsigned j=0; j < SECTOR_CHUNCK_SIZE; j++)
+ m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)) ;
+}
+
float tag_array::windowed_miss_rate( ) const
{
unsigned n_access = m_access - m_prev_snapshot_access;
@@ -1162,52 +1171,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
unsigned time, std::list<cache_event> &events,
enum cache_request_status status )
{
-
- 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 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())
@@ -1316,7 +1280,59 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
return MISS;
}
return RESERVATION_FAIL;
- }*/
+ }
+}
+
+enum cache_request_status
+data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr,
+ unsigned cache_index, mem_fetch *mf,
+ unsigned time, std::list<cache_event> &events,
+ enum cache_request_status status )
+{
+
+ 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;
}
/// 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 d2b7757..96b9a6d 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -454,7 +454,8 @@ enum allocation_policy_t {
enum write_allocate_policy_t {
NO_WRITE_ALLOCATE,
WRITE_ALLOCATE,
- FETCH_ON_WRITE
+ FETCH_ON_WRITE,
+ LAZY_FETCH_ON_READ
};
enum mshr_config_t {
@@ -555,6 +556,7 @@ public:
case 'N': m_write_alloc_policy = NO_WRITE_ALLOCATE; break;
case 'W': m_write_alloc_policy = WRITE_ALLOCATE; break;
case 'F': m_write_alloc_policy = FETCH_ON_WRITE; break;
+ case 'L': m_write_alloc_policy = LAZY_FETCH_ON_READ; break;
default: exit_parse_error();
}
@@ -572,9 +574,9 @@ public:
assert(0 && "Invalid cache configuration: Writeback cache cannot allocate new line on fill. ");
}
- if(m_write_alloc_policy == FETCH_ON_WRITE && m_alloc_policy == ON_FILL)
+ if((m_write_alloc_policy == FETCH_ON_WRITE || m_write_alloc_policy == LAZY_FETCH_ON_READ )&& m_alloc_policy == ON_FILL)
{
- assert(0 && "Invalid cache configuration: FETCH_ON_WRITE cannot work properly with ON_FILL policy. Cache must be ON_MISS. ");
+ assert(0 && "Invalid cache configuration: FETCH_ON_WRITE and LAZY_FETCH_ON_READ cannot work properly with ON_FILL policy. Cache must be ON_MISS. ");
}
if(m_cache_type == SECTOR)
{
@@ -742,7 +744,8 @@ public:
unsigned size() const { return m_config.get_num_lines();}
cache_block_t* get_block(unsigned idx) { return m_lines[idx];}
- void flush(); // flash invalidate all entries
+ void flush(); // flush all written entries
+ void invalidate(); // invalidate all entries
void new_window();
void print( FILE *stream, unsigned &total_access, unsigned &total_misses ) const;
@@ -994,6 +997,7 @@ public:
mem_fetch *next_access(){return m_mshrs.next_access();}
// flash invalidate all entries in cache
void flush(){m_tag_array->flush();}
+ void invalidate(){m_tag_array->invalidate();}
void print(FILE *fp, unsigned &accesses, unsigned &misses) const;
void display_state( FILE *fp ) const;
@@ -1179,6 +1183,7 @@ public:
case NO_WRITE_ALLOCATE: m_wr_miss = &data_cache::wr_miss_no_wa; break;
case WRITE_ALLOCATE: m_wr_miss = &data_cache::wr_miss_wa_naive; break;
case FETCH_ON_WRITE: m_wr_miss = &data_cache::wr_miss_wa_fetch_on_write; break;
+ case LAZY_FETCH_ON_READ: m_wr_miss = &data_cache::wr_miss_wa_lazy_fetch_on_read; break;
default:
assert(0 && "Error: Must set valid cache write miss policy\n");
break; // Need to set a write miss function
@@ -1299,7 +1304,14 @@ protected:
mem_fetch *mf,
unsigned time,
std::list<cache_event> &events,
- enum cache_request_status status ); // write-allocate with read-fetch-only
+ enum cache_request_status status ); // write-allocate with fetch-on-every-write
+ enum cache_request_status
+ wr_miss_wa_lazy_fetch_on_read( new_addr_type addr,
+ unsigned cache_index,
+ mem_fetch *mf,
+ unsigned time,
+ std::list<cache_event> &events,
+ enum cache_request_status status ); // write-allocate with read-fetch-only
enum cache_request_status
wr_miss_wa_write_validate( new_addr_type addr,
unsigned cache_index,
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index c5d4464..d48de25 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -1548,12 +1548,12 @@ void gpgpu_sim::cycle()
issue_block2core();
- // Depending on configuration, flush the caches once all of threads are completed.
+ // Depending on configuration, invalidate the caches once all of threads are completed.
int all_threads_complete = 1;
if (m_config.gpgpu_flush_l1_cache) {
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
if (m_cluster[i]->get_not_completed() == 0)
- m_cluster[i]->cache_flush();
+ m_cluster[i]->cache_invalidate();
else
all_threads_complete = 0 ;
}
@@ -1575,7 +1575,7 @@ void gpgpu_sim::cycle()
int dlc = 0;
for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
dlc = m_memory_sub_partition[i]->flushL2();
- assert (dlc == 0); // need to model actual writes to DRAM here
+ assert (dlc == 0); // TODO: need to model actual writes to DRAM here
printf("Dirty lines flushed from L2 %d is %d\n", i, dlc );
}
}
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index b1465a8..359d3c8 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -428,7 +428,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
m_icnt_L2_queue->pop();
}
} else if ( status != RESERVATION_FAIL ) {
- if(mf->is_write() && m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE && !was_writeallocate_sent(events)) {
+ if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) {
mf->set_reply();
mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
@@ -568,7 +568,15 @@ unsigned memory_sub_partition::flushL2()
if (!m_config->m_L2_config.disabled()) {
m_L2cache->flush();
}
- return 0; // L2 is read only in this version
+ return 0; //TODO: write the flushed data to the main memory
+}
+
+unsigned memory_sub_partition::invalidateL2()
+{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->invalidate();
+ }
+ return 0;
}
bool memory_sub_partition::busy() const
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index 2d13918..18c0a8b 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -162,6 +162,7 @@ public:
void set_done( mem_fetch *mf );
unsigned flushL2();
+ unsigned invalidateL2();
// interface to L2_dram_queue
bool L2_dram_queue_empty() const;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index d2f40a1..b660b8c 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -1593,6 +1593,11 @@ void ldst_unit::flush(){
m_L1D->flush();
}
+void ldst_unit::invalidate(){
+ // Flush L1D cache
+ m_L1D->invalidate();
+}
+
simd_function_unit::simd_function_unit( const shader_core_config *config )
{
m_config=config;
@@ -2644,6 +2649,11 @@ void shader_core_ctx::cache_flush()
m_ldst_unit->flush();
}
+void shader_core_ctx::cache_invalidate()
+{
+ m_ldst_unit->invalidate();
+}
+
// modifiers
std::list<opndcoll_rfu_t::op_t> opndcoll_rfu_t::arbiter_t::allocate_reads()
{
@@ -3461,6 +3471,12 @@ void simt_core_cluster::cache_flush()
m_core[i]->cache_flush();
}
+void simt_core_cluster::cache_invalidate()
+{
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ m_core[i]->cache_invalidate();
+}
+
bool simt_core_cluster::icnt_injection_buffer_full(unsigned size, bool write)
{
unsigned request_size = size;
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index ae22eaa..cc441b3 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1155,6 +1155,7 @@ public:
void fill( mem_fetch *mf );
void flush();
+ void invalidate();
void writeback();
// accessors
@@ -1655,6 +1656,7 @@ public:
void issue_block2core( class kernel_info_t &kernel );
void cache_flush();
+ void cache_invalidate();
void accept_fetch_response( mem_fetch *mf );
void accept_ldst_unit_response( class mem_fetch * mf );
void broadcast_barrier_reduction(unsigned cta_id, unsigned bar_id,warp_set_t warps);
@@ -1947,6 +1949,7 @@ public:
void reinit();
unsigned issue_block2core();
void cache_flush();
+ void cache_invalidate();
bool icnt_injection_buffer_full(unsigned size, bool write);
void icnt_inject_request_packet(class mem_fetch *mf);