summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/gpu-cache.cc')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc247
1 files changed, 172 insertions, 75 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 75c3691..3a5a67d 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -1,18 +1,21 @@
-// Copyright (c) 2009-2011, Tor M. Aamodt, Tayler Hetherington
-// The University of British Columbia
+// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington,
+// Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan,
+// Timothy G. Rogers
+// The University of British Columbia, Northwestern University, Purdue University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
-// Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-// Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution. Neither the name of
-// The University of British Columbia nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer;
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution;
+// 3. Neither the names of The University of British Columbia, Northwestern
+// University nor the names of their contributors may be used to
+// endorse or promote products derived from this software without specific
+// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -37,7 +40,8 @@
const char *cache_request_status_str(enum cache_request_status status) {
static const char *static_cache_request_status_str[] = {
- "HIT", "HIT_RESERVED", "MISS", "RESERVATION_FAIL", "SECTOR_MISS"};
+ "HIT", "HIT_RESERVED", "MISS", "RESERVATION_FAIL",
+ "SECTOR_MISS", "MSHR_HIT"};
assert(sizeof(static_cache_request_status_str) / sizeof(const char *) ==
NUM_CACHE_REQUEST_STATUS);
@@ -63,9 +67,9 @@ unsigned l1d_cache_config::set_bank(new_addr_type addr) const {
// For sector cache, we select one sector per bank (sector interleaving)
// This is what was found in Volta (one sector per bank, sector interleaving)
// otherwise, line interleaving
- return cache_config::hash_function(addr, l1_banks, l1_banks_byte_interleaving,
- m_l1_banks_log2,
- l1_banks_hashing_function);
+ return cache_config::hash_function(addr, l1_banks,
+ l1_banks_byte_interleaving_log2,
+ l1_banks_log2, l1_banks_hashing_function);
}
unsigned cache_config::set_index(new_addr_type addr) const {
@@ -210,6 +214,7 @@ void tag_array::init(int core_id, int type_id) {
m_core_id = core_id;
m_type_id = type_id;
is_used = false;
+ m_dirty = 0;
}
void tag_array::add_pending_line(mem_fetch *mf) {
@@ -231,15 +236,15 @@ void tag_array::remove_pending_line(mem_fetch *mf) {
}
enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
- mem_fetch *mf,
+ mem_fetch *mf, bool is_write,
bool probe_mode) const {
mem_access_sector_mask_t mask = mf->get_access_sector_mask();
- return probe(addr, idx, mask, probe_mode, mf);
+ return probe(addr, idx, mask, is_write, probe_mode, mf);
}
enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
mem_access_sector_mask_t mask,
- bool probe_mode,
+ bool is_write, bool probe_mode,
mem_fetch *mf) const {
// assert( m_config.m_write_policy == READ_ONLY );
unsigned set_index = m_config.set_index(addr);
@@ -250,7 +255,6 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
unsigned long long 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;
@@ -263,7 +267,7 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
idx = index;
return HIT;
} else if (line->get_status(mask) == MODIFIED) {
- if (line->is_readable(mask)) {
+ if ((!is_write && line->is_readable(mask)) || is_write) {
idx = index;
return HIT;
} else {
@@ -279,20 +283,31 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
}
}
if (!line->is_reserved_line()) {
- all_reserved = false;
- if (line->is_invalid_line()) {
- invalid_line = index;
- } else {
- // valid line : keep track of most appropriate replacement candidate
- if (m_config.m_replacement_policy == LRU) {
- if (line->get_last_access_time() < valid_timestamp) {
- valid_timestamp = line->get_last_access_time();
- valid_line = index;
- }
- } else if (m_config.m_replacement_policy == FIFO) {
- if (line->get_alloc_time() < valid_timestamp) {
- valid_timestamp = line->get_alloc_time();
- valid_line = index;
+ // percentage of dirty lines in the cache
+ // number of dirty lines / total lines in the cache
+ float dirty_line_percentage =
+ ((float)m_dirty / (m_config.m_nset * m_config.m_assoc)) * 100;
+ // If the cacheline is from a load op (not modified),
+ // or the total dirty cacheline is above a specific value,
+ // Then this cacheline is eligible to be considered for replacement candidate
+ // i.e. Only evict clean cachelines until total dirty cachelines reach the limit.
+ if (!line->is_modified_line() ||
+ dirty_line_percentage >= m_config.m_wr_percent) {
+ all_reserved = false;
+ if (line->is_invalid_line()) {
+ invalid_line = index;
+ } else {
+ // valid line : keep track of most appropriate replacement candidate
+ if (m_config.m_replacement_policy == LRU) {
+ if (line->get_last_access_time() < valid_timestamp) {
+ valid_timestamp = line->get_last_access_time();
+ valid_line = index;
+ }
+ } else if (m_config.m_replacement_policy == FIFO) {
+ if (line->get_alloc_time() < valid_timestamp) {
+ valid_timestamp = line->get_alloc_time();
+ valid_line = index;
+ }
}
}
}
@@ -312,15 +327,6 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
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;
}
@@ -340,7 +346,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time,
m_access++;
is_used = true;
shader_cache_access_log(m_core_id, m_type_id, 0); // log accesses to cache
- enum cache_request_status status = probe(addr, idx, mf);
+ enum cache_request_status status = probe(addr, idx, mf, mf->is_write());
switch (status) {
case HIT_RESERVED:
m_pending_hit++;
@@ -353,8 +359,12 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time,
if (m_config.m_alloc_policy == ON_MISS) {
if (m_lines[idx]->is_modified_line()) {
wb = true;
+ // m_lines[idx]->set_byte_mask(mf);
evicted.set_info(m_lines[idx]->m_block_addr,
- m_lines[idx]->get_modified_size());
+ m_lines[idx]->get_modified_size(),
+ m_lines[idx]->get_dirty_byte_mask(),
+ m_lines[idx]->get_dirty_sector_mask());
+ m_dirty--;
}
m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr),
time, mf->get_access_sector_mask());
@@ -365,8 +375,12 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time,
m_sector_miss++;
shader_cache_access_log(m_core_id, m_type_id, 1); // log cache misses
if (m_config.m_alloc_policy == ON_MISS) {
+ bool before = m_lines[idx]->is_modified_line();
((sector_cache_block *)m_lines[idx])
->allocate_sector(time, mf->get_access_sector_mask());
+ if (before && !m_lines[idx]->is_modified_line()) {
+ m_dirty--;
+ }
}
break;
case RESERVATION_FAIL:
@@ -383,31 +397,45 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time,
return status;
}
-void tag_array::fill(new_addr_type addr, unsigned time, mem_fetch *mf) {
- fill(addr, time, mf->get_access_sector_mask());
+void tag_array::fill(new_addr_type addr, unsigned time, mem_fetch *mf,
+ bool is_write) {
+ fill(addr, time, mf->get_access_sector_mask(), mf->get_access_byte_mask(),
+ is_write);
}
void tag_array::fill(new_addr_type addr, unsigned time,
- mem_access_sector_mask_t mask) {
+ mem_access_sector_mask_t mask,
+ mem_access_byte_mask_t byte_mask, bool is_write) {
// assert( m_config.m_alloc_policy == ON_FILL );
unsigned idx;
- enum cache_request_status status = probe(addr, idx, mask);
+ enum cache_request_status status = probe(addr, idx, mask, is_write);
+ bool before = m_lines[idx]->is_modified_line();
// assert(status==MISS||status==SECTOR_MISS); // MSHR should have prevented
// redundant memory request
- if (status == MISS)
+ if (status == MISS) {
m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time,
mask);
- else if (status == SECTOR_MISS) {
+ } else if (status == SECTOR_MISS) {
assert(m_config.m_cache_type == SECTOR);
((sector_cache_block *)m_lines[idx])->allocate_sector(time, mask);
}
-
- m_lines[idx]->fill(time, mask);
+ if (before && !m_lines[idx]->is_modified_line()) {
+ m_dirty--;
+ }
+ before = m_lines[idx]->is_modified_line();
+ m_lines[idx]->fill(time, mask, byte_mask);
+ if (m_lines[idx]->is_modified_line() && !before) {
+ m_dirty++;
+ }
}
void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) {
assert(m_config.m_alloc_policy == ON_MISS);
- m_lines[index]->fill(time, mf->get_access_sector_mask());
+ bool before = m_lines[index]->is_modified_line();
+ m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask());
+ if (m_lines[index]->is_modified_line() && !before) {
+ m_dirty++;
+ }
}
// TODO: we need write back the flushed data to the upper level
@@ -416,10 +444,12 @@ void tag_array::flush() {
for (unsigned i = 0; i < m_config.get_num_lines(); i++)
if (m_lines[i]->is_modified_line()) {
- for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++)
+ for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) {
m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j));
+ }
}
+ m_dirty = 0;
is_used = false;
}
@@ -430,6 +460,7 @@ void tag_array::invalidate() {
for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++)
m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j));
+ m_dirty = 0;
is_used = false;
}
@@ -485,8 +516,10 @@ bool was_writeback_sent(const std::list<cache_event> &events,
cache_event &wb_event) {
for (std::list<cache_event>::const_iterator e = events.begin();
e != events.end(); e++) {
- if ((*e).m_cache_event_type == WRITE_BACK_REQUEST_SENT) wb_event = *e;
- return true;
+ if ((*e).m_cache_event_type == WRITE_BACK_REQUEST_SENT) {
+ wb_event = *e;
+ return true;
+ }
}
return false;
}
@@ -612,6 +645,7 @@ void cache_stats::clear() {
///
for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) {
std::fill(m_stats[i].begin(), m_stats[i].end(), 0);
+ std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0);
std::fill(m_fail_stats[i].begin(), m_fail_stats[i].end(), 0);
}
m_cache_port_available_cycles = 0;
@@ -771,7 +805,9 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const {
cache_request_status_str((enum cache_request_status)status),
m_stats[type][status]);
- if (status != RESERVATION_FAIL)
+ if (status != RESERVATION_FAIL && status != MSHR_HIT)
+ // MSHR_HIT is a special type of SECTOR_MISS
+ // so its already included in the SECTOR_MISS
total_access[type] += m_stats[type][status];
}
}
@@ -1057,8 +1093,7 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) {
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) {
- m_tag_array->fill(e->second.m_block_addr, time, mf);
- if (m_config.is_streaming()) m_tag_array->remove_pending_line(mf);
+ m_tag_array->fill(e->second.m_block_addr, time, mf, mf->is_write());
} else
abort();
bool has_atomic = false;
@@ -1066,9 +1101,13 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) {
if (has_atomic) {
assert(m_config.m_alloc_policy == ON_MISS);
cache_block_t *block = m_tag_array->get_block(e->second.m_cache_index);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED,
mf->get_access_sector_mask()); // mark line as dirty for
// atomic operation
+ block->set_byte_mask(mf);
}
m_extra_mf_fields.erase(mf);
m_bandwidth_management.use_fill_port(mf);
@@ -1123,6 +1162,7 @@ void baseline_cache::send_read_request(new_addr_type addr,
m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf);
m_mshrs.add(mshr_addr, mf);
+ m_stats.inc_stats(mf->get_access_type(), MSHR_HIT);
do_miss = true;
} else if (!mshr_hit && mshr_avail &&
@@ -1133,9 +1173,6 @@ void baseline_cache::send_read_request(new_addr_type addr,
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());
@@ -1162,6 +1199,25 @@ void data_cache::send_write_request(mem_fetch *mf, cache_event request,
mf->set_status(m_miss_queue_status, time);
}
+void data_cache::update_m_readable(mem_fetch *mf, unsigned cache_index) {
+ cache_block_t *block = m_tag_array->get_block(cache_index);
+ for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; i++) {
+ if (mf->get_access_sector_mask().test(i)) {
+ bool all_set = true;
+ for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) {
+ // If any bit in the byte mask (within the sector) is not set,
+ // the sector is unreadble
+ if (!block->get_dirty_byte_mask().test(k)) {
+ all_set = false;
+ break;
+ }
+ }
+ if (all_set)
+ block->set_m_readable(true, mf->get_access_sector_mask());
+ }
+ }
+}
+
/****** Write-hit functions (Set by config file) ******/
/// Write-back hit: Mark block as modified
@@ -1173,7 +1229,12 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr,
new_addr_type block_addr = m_config.block_addr(addr);
m_tag_array->access(block_addr, time, cache_index, mf); // update LRU state
cache_block_t *block = m_tag_array->get_block(cache_index);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED, mf->get_access_sector_mask());
+ block->set_byte_mask(mf);
+ update_m_readable(mf,cache_index);
return HIT;
}
@@ -1192,7 +1253,12 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr,
new_addr_type block_addr = m_config.block_addr(addr);
m_tag_array->access(block_addr, time, cache_index, mf); // update LRU state
cache_block_t *block = m_tag_array->get_block(cache_index);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED, mf->get_access_sector_mask());
+ block->set_byte_mask(mf);
+ update_m_readable(mf,cache_index);
// generate a write-through
send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events);
@@ -1302,8 +1368,10 @@ enum cache_request_status data_cache::wr_miss_wa_naive(
assert(status ==
MISS); // SECTOR_MISS and HIT_RESERVED should not send write back
mem_fetch *wb = m_memfetch_creator->alloc(
- evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
+ evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
+ true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
+ NULL);
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1340,7 +1408,11 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf);
assert(status != HIT);
cache_block_t *block = m_tag_array->get_block(cache_index);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED, mf->get_access_sector_mask());
+ block->set_byte_mask(mf);
if (status == HIT_RESERVED)
block->set_ignore_on_fill(true, mf->get_access_sector_mask());
@@ -1349,8 +1421,10 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
// (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,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
+ evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
+ true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
+ NULL);
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1411,6 +1485,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
cache_block_t *block = m_tag_array->get_block(cache_index);
block->set_modified_on_fill(true, mf->get_access_sector_mask());
+ block->set_byte_mask_on_fill(true);
events.push_back(cache_event(WRITE_ALLOCATE_SENT));
@@ -1419,8 +1494,10 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
// (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,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
+ evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
+ true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
+ NULL);
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1448,6 +1525,10 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read(
return RESERVATION_FAIL; // cannot handle request this cycle
}
+ if (m_config.m_write_policy == WRITE_THROUGH) {
+ send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events);
+ }
+
bool wb = false;
evicted_block_info evicted;
@@ -1455,25 +1536,35 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read(
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);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED, mf->get_access_sector_mask());
+ block->set_byte_mask(mf);
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());
+ block->set_byte_mask_on_fill(true);
}
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 == HIT_RESERVED)
+ block->set_readable_on_fill(true, mf->get_access_sector_mask());
}
+ update_m_readable(mf,cache_index);
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,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
+ evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
+ true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
+ NULL);
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1516,8 +1607,12 @@ enum cache_request_status data_cache::rd_hit_base(
if (mf->isatomic()) {
assert(mf->get_access_type() == GLOBAL_ACC_R);
cache_block_t *block = m_tag_array->get_block(cache_index);
+ if (!block->is_modified_line()) {
+ m_tag_array->inc_dirty();
+ }
block->set_status(MODIFIED,
- mf->get_access_sector_mask()); // mark line as dirty
+ mf->get_access_sector_mask()); // mark line as
+ block->set_byte_mask(mf);
}
return HIT;
}
@@ -1548,8 +1643,10 @@ enum cache_request_status data_cache::rd_miss_base(
// (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,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
+ evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
+ true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
+ NULL);
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1572,7 +1669,7 @@ enum cache_request_status read_only_cache::access(
new_addr_type block_addr = m_config.block_addr(addr);
unsigned cache_index = (unsigned)-1;
enum cache_request_status status =
- m_tag_array->probe(block_addr, cache_index, mf);
+ m_tag_array->probe(block_addr, cache_index, mf, mf->is_write());
enum cache_request_status cache_status = RESERVATION_FAIL;
if (status == HIT) {
@@ -1659,7 +1756,7 @@ enum cache_request_status data_cache::access(new_addr_type addr, mem_fetch *mf,
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, true);
+ m_tag_array->probe(block_addr, cache_index, mf, mf->is_write(), 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(),