summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorTimothy G Rogers <[email protected]>2018-10-11 23:34:23 -0400
committerGitHub Enterprise <[email protected]>2018-10-11 23:34:23 -0400
commit207061fe774859ede7cf908234a131effacfba0e (patch)
treec54510984134878ca193bddb65d5dbefd663578d /src/gpgpu-sim
parent982d7e02ff64c8978d5635bbc2b3515e2145574b (diff)
parente283a267dfe4978863e6cc6cd9492927715c5815 (diff)
Merge pull request #29 from abdallm/dev-purdue-integration
count misses of pending req as sector miss in streaming cache
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc44
-rw-r--r--src/gpgpu-sim/gpu-cache.h18
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;