summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-cache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/gpu-cache.h')
-rw-r--r--src/gpgpu-sim/gpu-cache.h98
1 files changed, 87 insertions, 11 deletions
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 87a6b13..578fadb 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -72,14 +72,26 @@ enum cache_event_type {
struct evicted_block_info {
new_addr_type m_block_addr;
unsigned m_modified_size;
+ mem_access_byte_mask_t m_byte_mask;
+ mem_access_sector_mask_t m_sector_mask;
evicted_block_info() {
m_block_addr = 0;
m_modified_size = 0;
+ m_byte_mask.reset();
+ m_sector_mask.reset();
}
void set_info(new_addr_type block_addr, unsigned modified_size) {
m_block_addr = block_addr;
m_modified_size = modified_size;
}
+ void set_info(new_addr_type block_addr, unsigned modified_size,
+ mem_access_byte_mask_t byte_mask,
+ mem_access_sector_mask_t sector_mask) {
+ m_block_addr = block_addr;
+ m_modified_size = modified_size;
+ m_byte_mask = byte_mask;
+ m_sector_mask = sector_mask;
+ }
};
struct cache_event {
@@ -109,7 +121,8 @@ struct cache_block_t {
virtual void allocate(new_addr_type tag, new_addr_type block_addr,
unsigned time,
mem_access_sector_mask_t sector_mask) = 0;
- virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask) = 0;
+ virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask,
+ mem_access_byte_mask_t byte_mask) = 0;
virtual bool is_invalid_line() = 0;
virtual bool is_valid_line() = 0;
@@ -120,7 +133,10 @@ struct cache_block_t {
mem_access_sector_mask_t sector_mask) = 0;
virtual void set_status(enum cache_block_state m_status,
mem_access_sector_mask_t sector_mask) = 0;
-
+ virtual void set_byte_mask(mem_fetch *mf) = 0;
+ virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) = 0;
+ virtual mem_access_byte_mask_t get_dirty_byte_mask() = 0;
+ virtual mem_access_sector_mask_t get_dirty_sector_mask() = 0;
virtual unsigned long long get_last_access_time() = 0;
virtual void set_last_access_time(unsigned long long time,
mem_access_sector_mask_t sector_mask) = 0;
@@ -131,6 +147,7 @@ struct cache_block_t {
mem_access_sector_mask_t sector_mask) = 0;
virtual void set_readable_on_fill(bool readable,
mem_access_sector_mask_t sector_mask) = 0;
+ virtual void set_byte_mask_on_fill(bool m_modified) = 0;
virtual unsigned get_modified_size() = 0;
virtual void set_m_readable(bool readable,
mem_access_sector_mask_t sector_mask) = 0;
@@ -164,8 +181,10 @@ struct line_cache_block : public cache_block_t {
m_ignore_on_fill_status = false;
m_set_modified_on_fill = false;
m_set_readable_on_fill = false;
+ m_set_byte_mask_on_fill = false;
}
- void fill(unsigned time, mem_access_sector_mask_t sector_mask) {
+ virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask,
+ mem_access_byte_mask_t byte_mask) {
// if(!m_ignore_on_fill_status)
// assert( m_status == RESERVED );
@@ -173,6 +192,7 @@ struct line_cache_block : public cache_block_t {
if (m_set_readable_on_fill)
m_readable = true;
+ if (m_set_byte_mask_on_fill) set_byte_mask(byte_mask);
m_fill_time = time;
}
@@ -189,6 +209,20 @@ struct line_cache_block : public cache_block_t {
mem_access_sector_mask_t sector_mask) {
m_status = status;
}
+ virtual void set_byte_mask(mem_fetch *mf) {
+ m_byte_mask = m_byte_mask | mf->get_access_byte_mask();
+ }
+ virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) {
+ m_byte_mask = m_byte_mask | byte_mask;
+ }
+ virtual mem_access_byte_mask_t get_dirty_byte_mask() {
+ return m_byte_mask;
+ }
+ virtual mem_access_sector_mask_t get_dirty_sector_mask() {
+ mem_access_sector_mask_t sector_mask;
+ if (m_status == MODIFIED) sector_mask.set();
+ return sector_mask;
+ }
virtual unsigned long long get_last_access_time() {
return m_last_access_time;
}
@@ -209,6 +243,9 @@ struct line_cache_block : public cache_block_t {
mem_access_sector_mask_t sector_mask) {
m_set_readable_on_fill = readable;
}
+ virtual void set_byte_mask_on_fill(bool m_modified) {
+ m_set_byte_mask_on_fill = m_modified;
+ }
virtual unsigned get_modified_size() {
return SECTOR_CHUNCK_SIZE * SECTOR_SIZE; // i.e. cache line size
}
@@ -231,7 +268,9 @@ struct line_cache_block : public cache_block_t {
bool m_ignore_on_fill_status;
bool m_set_modified_on_fill;
bool m_set_readable_on_fill;
+ bool m_set_byte_mask_on_fill;
bool m_readable;
+ mem_access_byte_mask_t m_byte_mask;
};
struct sector_cache_block : public cache_block_t {
@@ -251,6 +290,7 @@ struct sector_cache_block : public cache_block_t {
m_line_alloc_time = 0;
m_line_last_access_time = 0;
m_line_fill_time = 0;
+ m_byte_mask.reset();
}
virtual void allocate(new_addr_type tag, new_addr_type block_addr,
@@ -276,6 +316,7 @@ struct sector_cache_block : public cache_block_t {
m_ignore_on_fill_status[sidx] = false;
m_set_modified_on_fill[sidx] = false;
m_set_readable_on_fill[sidx] = false;
+ m_set_byte_mask_on_fill = false;
// set line stats
m_line_alloc_time = time; // only set this for the first allocated sector
@@ -310,18 +351,19 @@ struct sector_cache_block : public cache_block_t {
m_line_fill_time = 0;
}
- virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask) {
+ virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask,
+ mem_access_byte_mask_t byte_mask) {
unsigned sidx = get_sector_index(sector_mask);
// if(!m_ignore_on_fill_status[sidx])
// assert( m_status[sidx] == RESERVED );
-
m_status[sidx] = m_set_modified_on_fill[sidx] ? MODIFIED : VALID;
if (m_set_readable_on_fill[sidx]) {
m_readable[sidx] = true;
m_set_readable_on_fill[sidx] = false;
}
+ if (m_set_byte_mask_on_fill) set_byte_mask(byte_mask);
m_sector_fill_time[sidx] = time;
m_line_fill_time = time;
@@ -362,6 +404,23 @@ struct sector_cache_block : public cache_block_t {
m_status[sidx] = status;
}
+ virtual void set_byte_mask(mem_fetch *mf) {
+ m_byte_mask = m_byte_mask | mf->get_access_byte_mask();
+ }
+ virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) {
+ m_byte_mask = m_byte_mask | byte_mask;
+ }
+ virtual mem_access_byte_mask_t get_dirty_byte_mask() {
+ return m_byte_mask;
+ }
+ virtual mem_access_sector_mask_t get_dirty_sector_mask() {
+ mem_access_sector_mask_t sector_mask;
+ for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; i++) {
+ if (m_status[i] == MODIFIED)
+ sector_mask.set(i);
+ }
+ return sector_mask;
+ }
virtual unsigned long long get_last_access_time() {
return m_line_last_access_time;
}
@@ -387,6 +446,9 @@ 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_byte_mask_on_fill(bool m_modified) {
+ m_set_byte_mask_on_fill = m_modified;
+ }
virtual void set_readable_on_fill(bool readable,
mem_access_sector_mask_t sector_mask) {
@@ -428,7 +490,9 @@ struct sector_cache_block : public cache_block_t {
bool m_ignore_on_fill_status[SECTOR_CHUNCK_SIZE];
bool m_set_modified_on_fill[SECTOR_CHUNCK_SIZE];
bool m_set_readable_on_fill[SECTOR_CHUNCK_SIZE];
+ bool m_set_byte_mask_on_fill;
bool m_readable[SECTOR_CHUNCK_SIZE];
+ mem_access_byte_mask_t m_byte_mask;
unsigned get_sector_index(mem_access_sector_mask_t sector_mask) {
assert(sector_mask.count() == 1);
@@ -499,10 +563,10 @@ class cache_config {
char ct, rp, wp, ap, mshr_type, wap, sif;
int ntok =
- sscanf(config, "%c:%u:%u:%u,%c:%c:%c:%c:%c,%c:%u:%u,%u:%u,%u", &ct,
+ sscanf(config, "%c:%u:%u:%u,%c:%c:%c:%c:%c,%c:%u:%u,%u:%u,%u,%u", &ct,
&m_nset, &m_line_sz, &m_assoc, &rp, &wp, &ap, &wap, &sif,
&mshr_type, &m_mshr_entries, &m_mshr_max_merge,
- &m_miss_queue_size, &m_result_fifo_entries, &m_data_port_width);
+ &m_miss_queue_size, &m_result_fifo_entries, &m_data_port_width, &m_wr_percent);
if (ntok < 12) {
if (!strcmp(config, "none")) {
@@ -771,6 +835,9 @@ class cache_config {
write_allocate_policy_t get_write_allocate_policy() {
return m_write_alloc_policy;
}
+ write_policy_t get_write_policy() {
+ return m_write_policy;
+ }
protected:
void exit_parse_error() {
@@ -819,6 +886,7 @@ class cache_config {
unsigned m_data_port_width; //< number of byte the cache can access per cycle
enum set_index_function
m_set_index_function; // Hash, linear, or custom set index function
+ unsigned m_wr_percent;
friend class tag_array;
friend class baseline_cache;
@@ -864,9 +932,11 @@ class tag_array {
~tag_array();
enum cache_request_status probe(new_addr_type addr, unsigned &idx,
- mem_fetch *mf, bool probe_mode = false) const;
+ mem_fetch *mf, bool is_write,
+ bool probe_mode = false) const;
enum cache_request_status probe(new_addr_type addr, unsigned &idx,
mem_access_sector_mask_t mask,
+ bool is_write,
bool probe_mode = false,
mem_fetch *mf = NULL) const;
enum cache_request_status access(new_addr_type addr, unsigned time,
@@ -875,9 +945,10 @@ class tag_array {
unsigned &idx, bool &wb,
evicted_block_info &evicted, mem_fetch *mf);
- void fill(new_addr_type addr, unsigned time, mem_fetch *mf);
+ void fill(new_addr_type addr, unsigned time, mem_fetch *mf, bool is_write);
void fill(unsigned idx, unsigned time, mem_fetch *mf);
- void fill(new_addr_type addr, unsigned time, mem_access_sector_mask_t mask);
+ void fill(new_addr_type addr, unsigned time, mem_access_sector_mask_t mask,
+ mem_access_byte_mask_t byte_mask, bool is_write);
unsigned size() const { return m_config.get_num_lines(); }
cache_block_t *get_block(unsigned idx) { return m_lines[idx]; }
@@ -895,6 +966,9 @@ class tag_array {
void update_cache_parameters(cache_config &config);
void add_pending_line(mem_fetch *mf);
void remove_pending_line(mem_fetch *mf);
+ void inc_dirty() {
+ m_dirty++;
+ }
protected:
// This constructor is intended for use only from derived classes that wish to
@@ -915,6 +989,7 @@ class tag_array {
// allocated but not filled
unsigned m_res_fail;
unsigned m_sector_miss;
+ unsigned m_dirty;
// performance counters for calculating the amount of misses within a time
// window
@@ -1260,7 +1335,8 @@ class baseline_cache : public cache_t {
// something is read or written without doing anything else.
void force_tag_access(new_addr_type addr, unsigned time,
mem_access_sector_mask_t mask) {
- m_tag_array->fill(addr, time, mask);
+ mem_access_byte_mask_t byte_mask;
+ m_tag_array->fill(addr, time, mask, byte_mask, true);
}
protected: