summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-cache.cc
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-11-28 09:35:25 -0800
committerTor Aamodt <[email protected]>2010-11-28 09:35:25 -0800
commit23d096dd1f1d4f0387087ffff0605fbf349556d2 (patch)
tree18e39a86e83bc445ec37eb9485c2a5ace7c82074 /src/gpgpu-sim/gpu-cache.cc
parenta937a4b354b60999a011970d054cd6c478be130d (diff)
adding 1st level data cache
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 8153]
Diffstat (limited to 'src/gpgpu-sim/gpu-cache.cc')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc175
1 files changed, 96 insertions, 79 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index c746da7..594e683 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -70,25 +70,24 @@
tag_array::~tag_array()
{
- delete m_lines;
+ delete m_lines;
}
tag_array::tag_array( const cache_config &config, int core_id, int type_id )
- : m_config(config)
+: m_config(config)
{
- assert( m_config.m_write_policy == READ_ONLY );
- m_lines = new cache_block_t[ config.get_num_lines()];
+ assert( m_config.m_write_policy == READ_ONLY );
+ m_lines = new cache_block_t[ config.get_num_lines()];
- // initialize snapshot counters for visualizer
- m_prev_snapshot_access = 0;
- m_prev_snapshot_miss = 0;
- m_prev_snapshot_pending_hit = 0;
- m_core_id = core_id;
- m_type_id = type_id;
+ // initialize snapshot counters for visualizer
+ m_prev_snapshot_access = 0;
+ m_prev_snapshot_miss = 0;
+ m_prev_snapshot_pending_hit = 0;
+ m_core_id = core_id;
+ m_type_id = type_id;
}
-enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx ) const
-{
+enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx ) 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);
@@ -98,57 +97,70 @@ enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx )
unsigned valid_timestamp = (unsigned)-1;
bool all_reserved = true;
-
+
// check for hit or pending hit
for (unsigned way=0; way<m_config.m_assoc; way++) {
- unsigned index = set_index*m_config.m_assoc+way;
- cache_block_t *line = &m_lines[index];
- if (line->m_tag == tag) {
- if( line->m_status == RESERVED ) {
- idx = index;
- return HIT_RESERVED;
- } else if( line->m_status == VALID ) {
- idx = index;
- return HIT;
- } else {
- assert( line->m_status == INVALID );
- }
- }
- if(line->m_status != RESERVED) {
- all_reserved = false;
- if(line->m_status == INVALID) {
- invalid_line = index;
- } else {
- // valid line : keep track of most appropriate replacement candidate
- if( m_config.m_replacement_policy == LRU ) {
- if( line->m_last_access_time < valid_timestamp ) {
- valid_timestamp = line->m_last_access_time;
- valid_line = index;
- }
- } else if( m_config.m_replacement_policy == FIFO ) {
- if( line->m_alloc_time < valid_timestamp ) {
- valid_timestamp = line->m_alloc_time;
- valid_line = index;
- }
- }
- }
- }
- }
- if( all_reserved ) {
- assert( m_config.m_alloc_policy == ON_MISS );
- return RESERVATION_FAIL; // miss and not enough space in cache to allocate on miss
- }
+ unsigned index = set_index*m_config.m_assoc+way;
+ cache_block_t *line = &m_lines[index];
+ if (line->m_tag == tag) {
+ if ( line->m_status == RESERVED ) {
+ idx = index;
+ return HIT_RESERVED;
+ } else if ( line->m_status == VALID ) {
+ idx = index;
+ return HIT;
+ } else if ( line->m_status == MODIFIED ) {
+ idx = index;
+ return HIT;
+ } else {
+ assert( line->m_status == INVALID );
+ }
+ }
+ if (line->m_status != RESERVED) {
+ all_reserved = false;
+ if (line->m_status == INVALID) {
+ invalid_line = index;
+ } else {
+ // valid line : keep track of most appropriate replacement candidate
+ if ( m_config.m_replacement_policy == LRU ) {
+ if ( line->m_last_access_time < valid_timestamp ) {
+ valid_timestamp = line->m_last_access_time;
+ valid_line = index;
+ }
+ } else if ( m_config.m_replacement_policy == FIFO ) {
+ if ( line->m_alloc_time < valid_timestamp ) {
+ valid_timestamp = line->m_alloc_time;
+ valid_line = index;
+ }
+ }
+ }
+ }
+ }
+ if ( all_reserved ) {
+ assert( m_config.m_alloc_policy == ON_MISS );
+ return RESERVATION_FAIL; // miss and not enough space in cache to allocate on miss
+ }
- if( invalid_line != (unsigned)-1 ) {
- idx = invalid_line;
- } else if( valid_line != (unsigned)-1) {
- idx = valid_line;
- } else abort(); // if an unreserved block exists, it is either invalid or replaceable
+ if ( invalid_line != (unsigned)-1 ) {
+ idx = invalid_line;
+ } else if ( valid_line != (unsigned)-1) {
+ idx = valid_line;
+ } else abort(); // if an unreserved block exists, it is either invalid or replaceable
- return MISS;
+ return MISS;
}
-enum cache_request_status tag_array::access( new_addr_type addr, unsigned time, unsigned &idx ) {
+enum cache_request_status tag_array::access( new_addr_type addr, unsigned time, unsigned &idx )
+{
+ bool wb=false;
+ cache_block_t evicted;
+ enum cache_request_status result = access(addr,time,idx,wb,evicted);
+ assert(!wb);
+ return result;
+}
+
+enum cache_request_status tag_array::access( new_addr_type addr, unsigned time, unsigned &idx, bool &wb, cache_block_t &evicted )
+{
m_access++;
shader_cache_access_log(m_core_id, m_type_id, 0); // log accesses to cache
enum cache_request_status status = probe(addr,idx);
@@ -161,8 +173,13 @@ enum cache_request_status tag_array::access( new_addr_type addr, unsigned time,
case MISS:
m_miss++;
shader_cache_access_log(m_core_id, m_type_id, 1); // log cache misses
- if ( m_config.m_alloc_policy == ON_MISS )
+ if ( m_config.m_alloc_policy == ON_MISS ) {
+ if( m_lines[idx].m_status == MODIFIED ) {
+ wb = true;
+ evicted = m_lines[idx];
+ }
m_lines[idx].allocate( m_config.tag(addr), m_config.block_addr(addr), time );
+ }
break;
case RESERVATION_FAIL:
m_miss++;
@@ -190,37 +207,37 @@ void tag_array::fill( unsigned index, unsigned time )
void tag_array::flush()
{
- for (unsigned i=0; i < m_config.get_num_lines(); i++)
- m_lines[i].m_status = INVALID;
+ for (unsigned i=0; i < m_config.get_num_lines(); i++)
+ m_lines[i].m_status = INVALID;
}
float tag_array::windowed_miss_rate( bool minus_pending_hit ) const
{
- unsigned n_access = m_access - m_prev_snapshot_access;
- unsigned n_miss = m_miss - m_prev_snapshot_miss;
- unsigned n_pending_hit = m_pending_hit - m_prev_snapshot_pending_hit;
-
- if (minus_pending_hit)
- n_miss -= n_pending_hit;
- float missrate = 0.0f;
- if (n_access != 0)
- missrate = (float) n_miss / n_access;
- return missrate;
+ unsigned n_access = m_access - m_prev_snapshot_access;
+ unsigned n_miss = m_miss - m_prev_snapshot_miss;
+ unsigned n_pending_hit = m_pending_hit - m_prev_snapshot_pending_hit;
+
+ if (minus_pending_hit)
+ n_miss -= n_pending_hit;
+ float missrate = 0.0f;
+ if (n_access != 0)
+ missrate = (float) n_miss / n_access;
+ return missrate;
}
void tag_array::new_window()
{
- m_prev_snapshot_access = m_access;
- m_prev_snapshot_miss = m_miss;
- m_prev_snapshot_pending_hit = m_pending_hit;
+ m_prev_snapshot_access = m_access;
+ m_prev_snapshot_miss = m_miss;
+ m_prev_snapshot_pending_hit = m_pending_hit;
}
void tag_array::print( FILE *stream, unsigned &total_access, unsigned &total_misses ) const
{
- m_config.print(stream);
- fprintf( stream, "\t\tAccess = %d, Miss = %d (%.3g), -MgHts = %d (%.3g)\n",
- m_access, m_miss, (float) m_miss / m_access,
- m_miss - m_pending_hit, (float) (m_miss - m_pending_hit) / m_access);
- total_misses+=m_miss;
- total_access+=m_access;
+ m_config.print(stream);
+ fprintf( stream, "\t\tAccess = %d, Miss = %d (%.3g), -MgHts = %d (%.3g)\n",
+ m_access, m_miss, (float) m_miss / m_access,
+ m_miss - m_pending_hit, (float) (m_miss - m_pending_hit) / m_access);
+ total_misses+=m_miss;
+ total_access+=m_access;
}