From b7b9dc0b35a836dedb02b109c9d4a79a0db2aaca Mon Sep 17 00:00:00 2001 From: Gwen Date: Mon, 26 Oct 2020 15:19:38 -0600 Subject: Fix for bugs in lazy write handling --- src/gpgpu-sim/gpu-cache.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 5c28b41..25d0b78 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -128,6 +128,8 @@ struct cache_block_t { mem_access_sector_mask_t sector_mask) = 0; virtual void set_modified_on_fill(bool m_modified, 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 unsigned get_modified_size() = 0; virtual void set_m_readable(bool readable, mem_access_sector_mask_t sector_mask) = 0; @@ -147,6 +149,7 @@ struct line_cache_block : public cache_block_t { m_status = INVALID; m_ignore_on_fill_status = false; m_set_modified_on_fill = false; + m_set_readable_on_fill = false; m_readable = true; } void allocate(new_addr_type tag, new_addr_type block_addr, unsigned time, @@ -159,12 +162,16 @@ struct line_cache_block : public cache_block_t { m_status = RESERVED; m_ignore_on_fill_status = false; m_set_modified_on_fill = false; + m_set_readable_on_fill = false; } void fill(unsigned time, mem_access_sector_mask_t sector_mask) { // if(!m_ignore_on_fill_status) // assert( m_status == RESERVED ); m_status = m_set_modified_on_fill ? MODIFIED : VALID; + + if (m_set_readable_on_fill) + m_readable = true; m_fill_time = time; } @@ -197,6 +204,10 @@ struct line_cache_block : public cache_block_t { mem_access_sector_mask_t sector_mask) { m_set_modified_on_fill = m_modified; } + virtual void set_readable_on_fill(bool readable, + mem_access_sector_mask_t sector_mask) { + m_set_readable_on_fill = readable; + } virtual unsigned get_modified_size() { return SECTOR_CHUNCK_SIZE * SECTOR_SIZE; // i.e. cache line size } @@ -218,6 +229,7 @@ struct line_cache_block : public cache_block_t { cache_block_state m_status; bool m_ignore_on_fill_status; bool m_set_modified_on_fill; + bool m_set_readable_on_fill; bool m_readable; }; @@ -232,6 +244,7 @@ struct sector_cache_block : public cache_block_t { m_status[i] = INVALID; m_ignore_on_fill_status[i] = false; m_set_modified_on_fill[i] = false; + m_set_readable_on_fill[i] = false; m_readable[i] = true; } m_line_alloc_time = 0; @@ -261,6 +274,7 @@ struct sector_cache_block : public cache_block_t { m_status[sidx] = RESERVED; m_ignore_on_fill_status[sidx] = false; m_set_modified_on_fill[sidx] = false; + m_set_readable_on_fill[sidx] = false; // set line stats m_line_alloc_time = time; // only set this for the first allocated sector @@ -283,6 +297,8 @@ struct sector_cache_block : public cache_block_t { else m_set_modified_on_fill[sidx] = false; + m_set_readable_on_fill[sidx] = false; + m_status[sidx] = RESERVED; m_ignore_on_fill_status[sidx] = false; // m_set_modified_on_fill[sidx] = false; @@ -300,6 +316,11 @@ struct sector_cache_block : public cache_block_t { // 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; + } m_sector_fill_time[sidx] = time; m_line_fill_time = time; @@ -366,6 +387,11 @@ struct sector_cache_block : public cache_block_t { m_set_modified_on_fill[sidx] = m_modified; } + virtual void set_readable_on_fill(bool readable, + mem_access_sector_mask_t sector_mask) { + unsigned sidx = get_sector_index(sector_mask); + m_set_readable_on_fill[sidx] = readable; + } virtual void set_m_readable(bool readable, mem_access_sector_mask_t sector_mask) { unsigned sidx = get_sector_index(sector_mask); @@ -400,6 +426,7 @@ struct sector_cache_block : public cache_block_t { cache_block_state m_status[SECTOR_CHUNCK_SIZE]; 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_readable[SECTOR_CHUNCK_SIZE]; unsigned get_sector_index(mem_access_sector_mask_t sector_mask) { -- cgit v1.3 From 132c2ce4ef3ff12f984881ca4b6a8780797dacff Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Sun, 15 Nov 2020 15:41:39 -0500 Subject: added MSHR_HIT --- src/gpgpu-sim/gpu-cache.cc | 3 ++- src/gpgpu-sim/gpu-cache.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 75c3691..613403a 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -37,7 +37,7 @@ 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); @@ -1123,6 +1123,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 && diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 5c28b41..17c8c02 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -49,6 +49,7 @@ enum cache_request_status { MISS, RESERVATION_FAIL, SECTOR_MISS, + MSHR_HIT, NUM_CACHE_REQUEST_STATUS }; -- cgit v1.3 From 51d99259845a051a32e45763bdf3005b4dff74b5 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 15 Feb 2021 16:03:51 -0500 Subject: fix hash funciton --- src/gpgpu-sim/gpu-cache.cc | 4 ++-- src/gpgpu-sim/gpu-cache.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 8f7ccd5..1c36d22 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -63,8 +63,8 @@ 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, + return cache_config::hash_function(addr, l1_banks, l1_banks_byte_interleaving_log2, + l1_banks_log2, l1_banks_hashing_function); } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 26369c3..00c09ae 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -817,15 +817,15 @@ class l1d_cache_config : public cache_config { l1d_cache_config() : cache_config() {} unsigned set_bank(new_addr_type addr) const; void init(char *config, FuncCache status) { - m_banks_byte_interleaving_log2 = LOGB2(l1_banks_byte_interleaving); - m_l1_banks_log2 = LOGB2(l1_banks); + l1_banks_byte_interleaving_log2 = LOGB2(l1_banks_byte_interleaving); + l1_banks_log2 = LOGB2(l1_banks); cache_config::init(config, status); } unsigned l1_latency; unsigned l1_banks; - unsigned m_l1_banks_log2; + unsigned l1_banks_log2; unsigned l1_banks_byte_interleaving; - unsigned m_banks_byte_interleaving_log2; + unsigned l1_banks_byte_interleaving_log2; unsigned l1_banks_hashing_function; }; -- cgit v1.3 From f2a7d9ce6cd13977d97a0601d732551a5451ac71 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Sat, 15 May 2021 09:09:20 -0400 Subject: fixing streaming cache based on recent ubench --- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 2 +- src/gpgpu-sim/gpu-cache.cc | 13 --------- src/gpgpu-sim/gpu-cache.h | 38 ++++++++++++++++---------- src/gpgpu-sim/shader.cc | 15 ++++++++++ 4 files changed, 39 insertions(+), 29 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 3fa51ee..3af314c 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -116,7 +116,7 @@ -gpgpu_adaptive_cache_config 1 # Volta unified cache has four banks -gpgpu_l1_banks 4 --gpgpu_cache:dl1 S:1:128:256,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1 S:1:128:256,L:L:m:N:L,A:512:8,16:0,32 -gpgpu_shmem_size 98304 -gpgpu_shmem_sizeDefault 98304 -gpgpu_shmem_per_block 65536 diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 1c36d22..c6a125d 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -312,15 +312,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; } @@ -1060,7 +1051,6 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) { 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); } else abort(); bool has_atomic = false; @@ -1136,9 +1126,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()); diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 00c09ae..aa0a7e8 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -574,22 +574,26 @@ class cache_config { exit_parse_error(); } if (m_alloc_policy == STREAMING) { - // For streaming cache, we set the alloc policy to be on-fill to remove - // all line_alloc_fail stalls we set the MSHRs to be equal to max - // allocated cache lines. This is possible by moving TAG to be shared - // between cache line and MSHR enrty (i.e. for each cache line, there is - // an MSHR rntey associated with it) This is the easiest think we can - // think about to model (mimic) L1 streaming cache in Pascal and Volta - // Based on our microbenchmakrs, MSHRs entries have been increasing - // substantially in Pascal and Volta 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/ + /* + For streaming cache: + (1) we set the alloc policy to be on-fill to remove all line_alloc_fail stalls. + if the whole memory is allocated to the L1 cache, then make the allocation to be on_MISS + otherwise, make it ON_FILL to eliminate line allocation fails. + i.e. MSHR throughput is the same, independent on the L1 cache size/associativity + So, we set the allocation policy per kernel basis, see shader.cc, max_cta() function + + (2) We also set the MSHRs to be equal to max + allocated cache lines. This is possible by moving TAG to be shared + between cache line and MSHR enrty (i.e. for each cache line, there is + an MSHR rntey associated with it). This is the easiest think we can + think of to model (mimic) L1 streaming cache in Pascal and Volta + + 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) m_mshr_entries *= SECTOR_CHUNCK_SIZE; - m_mshr_max_merge = MAX_WARP_PER_SM; } switch (mshr_type) { case 'F': @@ -638,7 +642,8 @@ class cache_config { } // detect invalid configuration - if (m_alloc_policy == ON_FILL and m_write_policy == WRITE_BACK) { + if ((m_alloc_policy == ON_FILL || m_alloc_policy == STREAMING) + and m_write_policy == WRITE_BACK) { // A writeback cache with allocate-on-fill policy will inevitably lead to // deadlock: The deadlock happens when an incoming cache-fill evicts a // dirty line, generating a writeback request. If the memory subsystem is @@ -750,6 +755,9 @@ class cache_config { } bool is_streaming() { return m_is_streaming; } FuncCache get_cache_status() { return cache_status; } + void set_allocation_policy(enum allocation_policy_t alloc) { + m_alloc_policy = alloc; + } char *m_config_string; char *m_config_stringPrefL1; char *m_config_stringPrefShared; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index c6e7b8f..0ad9547 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3308,6 +3308,21 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { m_L1D_config.get_total_size_inKB()); } + if(m_L1D_config.is_streaming()) { + //for streaming cache, if the whole memory is allocated + //to the L1 cache, then make the allocation to be on_MISS + //otherwise, make it ON_FILL to eliminate line allocation fails + //i.e. MSHR throughput is the same, independent on the L1 cache size/associativity + if(total_shmed == 0) { + m_L1D_config.set_allocation_policy(ON_MISS); + printf("GPGPU-Sim: Reconfigure L1 allocation to ON_MISS\n"); + } + else { + m_L1D_config.set_allocation_policy(ON_FILL); + printf("GPGPU-Sim: Reconfigure L1 allocation to ON_FILL\n"); + } + } + k.cache_config_set = true; } -- cgit v1.3 From 134739518a4a0f8a66cbf8c8a44b1a0ce178f7d5 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Sat, 15 May 2021 09:15:38 -0400 Subject: adding the missing xoring hashing --- src/gpgpu-sim/gpu-cache.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index aa0a7e8..b2db1c5 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -689,6 +689,9 @@ class cache_config { case 'L': m_set_index_function = LINEAR_SET_FUNCTION; break; + case 'X': + m_set_index_function = BITWISE_XORING_FUNCTION; + break; default: exit_parse_error(); } -- cgit v1.3 From 0f3030542e1987543c5fd4e497f7d422422e73fa Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 15 Feb 2021 12:42:14 -0500 Subject: dirty counter added. NO increamenting yet --- src/gpgpu-sim/gpu-cache.cc | 24 +++++++++++++++--------- src/gpgpu-sim/gpu-cache.h | 6 ++++-- 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 1c36d22..763705f 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -284,15 +284,20 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, 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; + if (!line->get_status(mask) == MODIFIED || + 100 * m_dirty/(m_config.m_nset * m_config.m_assoc) >= m_config.m_wr_percent) { + // don't evict write until dirty lines reach threshold + // make sure at least 1 candidate is assigned + 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; + } } } } @@ -418,6 +423,7 @@ void tag_array::flush() { if (m_lines[i]->is_modified_line()) { for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); + m_dirty--; } is_used = false; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 00c09ae..9dbfe82 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -498,10 +498,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")) { @@ -801,6 +801,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; @@ -897,6 +898,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 -- cgit v1.3 From 615f173c25883fbc8db0363279e2eb216acb8c7e Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Sat, 20 Feb 2021 16:03:42 -0500 Subject: store ack for new waps --- src/gpgpu-sim/gpu-cache.h | 6 ++++++ src/gpgpu-sim/shader.cc | 12 ++++++++++++ 2 files changed, 18 insertions(+) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 9dbfe82..381ce94 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -754,6 +754,9 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; + write_allocate_policy_t get_write_allocate_policy() { + return m_write_alloc_policy; + } protected: void exit_parse_error() { @@ -878,6 +881,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 diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 14d9044..4769ca8 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1974,6 +1974,18 @@ void ldst_unit::L1_latency_queue_cycle() { } else { assert(status == MISS || status == HIT_RESERVED); l1_latency_queue[j][0] = NULL; + if (mf_next->get_inst().is_store() && + (m_config->m_L1D_config.get_write_allocate_policy() == FETCH_ON_WRITE || + m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && + !was_writeallocate_sent(events)) { + unsigned dec_ack = + (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC) + ? (mf_next->get_data_size() / SECTOR_SIZE) + : 1; + mf_next->set_reply(); + for (unsigned i = 0; i < dec_ack; ++i) m_core->store_ack(mf_next); + if (!write_sent && !read_sent) delete mf_next; + } } } -- cgit v1.3 From ad7204189b79be89575d969b305c529a31a2a765 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:30:27 -0500 Subject: sending cache block byte mask --- src/abstract_hardware_model.h | 6 ++++++ src/gpgpu-sim/gpu-cache.cc | 21 ++++++++++++++++----- src/gpgpu-sim/gpu-cache.h | 28 ++++++++++++++++++++++++++++ src/gpgpu-sim/l2cache.cc | 14 ++++++++++++++ src/gpgpu-sim/l2cache.h | 6 ++++++ src/gpgpu-sim/shader.cc | 15 +++++++++++++++ src/gpgpu-sim/shader.h | 6 ++++++ 7 files changed, 91 insertions(+), 5 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 982e416..e09acdb 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -869,6 +869,12 @@ class mem_fetch_allocator { virtual mem_fetch *alloc(const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const = 0; + virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, + unsigned long long cycle) const = 0; }; // the maximum number of destination, source, or address uarch operands in a diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 763705f..ded8004 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -358,8 +358,13 @@ 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; + ((sector_cache_block *)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(), + ((sector_cache_block *)m_lines[idx]) + ->get_byte_mask(), + ((sector_cache_block *)m_lines[idx]) + ->get_sector_mask()); } m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time, mf->get_access_sector_mask()); @@ -1464,6 +1469,8 @@ 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); + block->set_status(MODIFIED, mf->get_access_sector_mask()); + ((sector_cache_block *)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()); @@ -1484,8 +1491,10 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( // (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); // 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); @@ -1560,8 +1569,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); // 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); diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 381ce94..042c1d6 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 { @@ -251,6 +263,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, @@ -362,6 +375,20 @@ 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 mem_access_byte_mask_t get_byte_mask() { + return m_byte_mask; + } + virtual mem_access_sector_mask_t get_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; } @@ -429,6 +456,7 @@ struct sector_cache_block : public cache_block_t { bool m_set_modified_on_fill[SECTOR_CHUNCK_SIZE]; bool m_set_readable_on_fill[SECTOR_CHUNCK_SIZE]; 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); diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index ab6e5c2..cd04af5 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -57,6 +57,20 @@ mem_fetch *partition_mf_allocator::alloc(new_addr_type addr, return mf; } +mem_fetch *partition_mf_allocator::alloc(new_addr_type addr, + mem_access_type type, + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, + unsigned long long cycle) const { + mem_access_t access(type, addr, size, wr, active_mask, byte_mask, + sector_mask, m_memory_config->gpgpu_ctx); + mem_fetch *mf = + new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1, + -1, -1, m_memory_config, cycle); + return mf; +} memory_partition_unit::memory_partition_unit(unsigned partition_id, const memory_config *config, class memory_stats_t *stats, diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 3152db3..1f5d7c4 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -51,6 +51,12 @@ class partition_mf_allocator : public mem_fetch_allocator { virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const; + virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, + unsigned long long cycle) const; private: const memory_config *m_memory_config; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 4769ca8..4b4c98d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -61,6 +61,21 @@ mem_fetch *shader_core_mem_fetch_allocator::alloc( m_core_id, m_cluster_id, m_memory_config, cycle); return mf; } + +mem_fetch *shader_core_mem_fetch_allocator::alloc( + new_addr_type addr, mem_access_type type, + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, + unsigned long long cycle) const { + mem_access_t access(type, addr, size, wr, active_mask, byte_mask, + sector_mask, m_memory_config->gpgpu_ctx); + mem_fetch *mf = + new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1, + m_core_id, m_cluster_id, m_memory_config, cycle); + return mf; + } ///////////////////////////////////////////////////////////////////////////// std::list shader_core_ctx::get_regs_written(const inst_t &fvt) const { diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 8c02fd7..a7a2c02 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1872,6 +1872,12 @@ class shader_core_mem_fetch_allocator : public mem_fetch_allocator { } mem_fetch *alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const; + mem_fetch *alloc(new_addr_type addr, mem_access_type type, + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, + unsigned long long cycle) const; mem_fetch *alloc(const warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const { warp_inst_t inst_copy = inst; -- cgit v1.3 From 804ee9033d5c0d8f4e0b974734c4db42b55bd1dc Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 8 Mar 2021 13:29:13 -0500 Subject: sending byte mask for all policies --- src/gpgpu-sim/gpu-cache.cc | 35 ++++++++++++++++++++++------------- src/gpgpu-sim/gpu-cache.h | 17 +++++++++++++++-- 2 files changed, 37 insertions(+), 15 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 8d44f15..2cc75bb 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -358,13 +358,11 @@ 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; - ((sector_cache_block *)m_lines[idx])->set_byte_mask(mf); + m_lines[idx]->set_byte_mask(mf); evicted.set_info(m_lines[idx]->m_block_addr, m_lines[idx]->get_modified_size(), - ((sector_cache_block *)m_lines[idx]) - ->get_byte_mask(), - ((sector_cache_block *)m_lines[idx]) - ->get_sector_mask()); + m_lines[idx]->get_byte_mask(), + m_lines[idx]->get_sector_mask()); } m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time, mf->get_access_sector_mask()); @@ -1083,6 +1081,7 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) { 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); @@ -1189,6 +1188,7 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type 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); block->set_status(MODIFIED, mf->get_access_sector_mask()); + block->set_byte_mask(mf); return HIT; } @@ -1208,6 +1208,7 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type 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); block->set_status(MODIFIED, mf->get_access_sector_mask()); + block->set_byte_mask(mf); // generate a write-through send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); @@ -1317,8 +1318,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); // 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); @@ -1356,6 +1359,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( assert(status != HIT); cache_block_t *block = m_tag_array->get_block(cache_index); 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()); @@ -1364,8 +1368,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); // 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); @@ -1434,8 +1440,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); // 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); @@ -1471,7 +1479,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( assert(m_status != HIT); cache_block_t *block = m_tag_array->get_block(cache_index); block->set_status(MODIFIED, mf->get_access_sector_mask()); - ((sector_cache_block *)block)->set_byte_mask(mf); + 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()); @@ -1539,7 +1547,8 @@ enum cache_request_status data_cache::rd_hit_base( assert(mf->get_access_type() == GLOBAL_ACC_R); cache_block_t *block = m_tag_array->get_block(cache_index); 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; } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 042c1d6..eb811d7 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -132,7 +132,9 @@ 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 mem_access_byte_mask_t get_byte_mask() = 0; + virtual mem_access_sector_mask_t get_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; @@ -201,6 +203,17 @@ 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 mem_access_byte_mask_t get_byte_mask() { + return m_byte_mask; + } + virtual mem_access_sector_mask_t get_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; } @@ -244,6 +257,7 @@ struct line_cache_block : public cache_block_t { bool m_set_modified_on_fill; bool m_set_readable_on_fill; bool m_readable; + mem_access_byte_mask_t m_byte_mask; }; struct sector_cache_block : public cache_block_t { @@ -328,7 +342,6 @@ struct sector_cache_block : public cache_block_t { // 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]) { -- cgit v1.3 From b3dab5eec75f11c600bddc9a6dd3b22272363cca Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 8 Mar 2021 15:02:58 -0500 Subject: set byte mask on fill --- src/gpgpu-sim/gpu-cache.cc | 12 ++++++------ src/gpgpu-sim/gpu-cache.h | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 2cc75bb..46813e7 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -392,11 +392,11 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, } void tag_array::fill(new_addr_type addr, unsigned time, mem_fetch *mf) { - fill(addr, time, mf->get_access_sector_mask()); + fill(addr, time, mf->get_access_sector_mask(), mf->get_access_byte_mask()); } 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) { // assert( m_config.m_alloc_policy == ON_FILL ); unsigned idx; enum cache_request_status status = probe(addr, idx, mask); @@ -410,12 +410,12 @@ void tag_array::fill(new_addr_type addr, unsigned time, ((sector_cache_block *)m_lines[idx])->allocate_sector(time, mask); } - m_lines[idx]->fill(time, mask); + m_lines[idx]->fill(time, mask, byte_mask); } 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()); + m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask()); } // TODO: we need write back the flushed data to the upper level @@ -1432,6 +1432,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)); @@ -1483,8 +1484,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( 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()); - } else { - block->set_status(MODIFIED, mf->get_access_sector_mask()); + block->set_byte_mask_on_fill(true); } if (mf->get_access_byte_mask().count() == m_config.get_atom_sz()) { diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index eb811d7..a84ddd1 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -121,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; @@ -133,6 +134,7 @@ struct cache_block_t { 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_byte_mask() = 0; virtual mem_access_sector_mask_t get_sector_mask() = 0; virtual unsigned long long get_last_access_time() = 0; @@ -145,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; @@ -178,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 ); @@ -187,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; } @@ -206,6 +212,9 @@ struct line_cache_block : public cache_block_t { 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_byte_mask() { return m_byte_mask; } @@ -234,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 } @@ -256,6 +268,7 @@ 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; }; @@ -303,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 @@ -337,7 +351,8 @@ 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]) @@ -348,6 +363,7 @@ struct sector_cache_block : public cache_block_t { 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; @@ -389,7 +405,10 @@ struct sector_cache_block : public cache_block_t { } virtual void set_byte_mask(mem_fetch *mf) { - m_byte_mask = m_byte_mask | mf->get_access_byte_mask();; + 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_byte_mask() { return m_byte_mask; @@ -427,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) { @@ -468,6 +490,7 @@ 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; @@ -904,7 +927,8 @@ class tag_array { void fill(new_addr_type addr, unsigned time, mem_fetch *mf); 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); unsigned size() const { return m_config.get_num_lines(); } cache_block_t *get_block(unsigned idx) { return m_lines[idx]; } @@ -1291,7 +1315,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); } protected: -- cgit v1.3 From f6fb56ba32141030803ecfe01b52a6f6c93d8e6c Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 6 Apr 2021 15:46:03 -0400 Subject: check sector readable only on reads --- src/gpgpu-sim/gpu-cache.cc | 27 ++++++++++++++------------- src/gpgpu-sim/gpu-cache.h | 10 ++++++---- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index d2f9fef..9c65476 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -232,15 +232,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); @@ -279,7 +279,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 { @@ -363,7 +363,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++; @@ -414,16 +414,17 @@ 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(), mf->get_access_byte_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_byte_mask_t byte_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); - bool before = false; + 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) { @@ -1105,7 +1106,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); + m_tag_array->fill(e->second.m_block_addr, time, mf, mf->is_write()); if (m_config.is_streaming()) m_tag_array->remove_pending_line(mf); } else abort(); @@ -1659,7 +1660,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) { @@ -1746,7 +1747,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(), diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index a84ddd1..c2e302e 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -914,9 +914,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, @@ -925,10 +927,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, - mem_access_byte_mask_t byte_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]; } @@ -1316,7 +1318,7 @@ class baseline_cache : public cache_t { void force_tag_access(new_addr_type addr, unsigned time, mem_access_sector_mask_t mask) { mem_access_byte_mask_t byte_mask; - m_tag_array->fill(addr, time, mask, byte_mask); + m_tag_array->fill(addr, time, mask, byte_mask, true); } protected: -- cgit v1.3 From 0601354a4d7f7f106e008b47cbc74097ec0a2a69 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 18 May 2021 14:35:04 -0400 Subject: Add WT to lazy_fetch_on_read --- src/gpgpu-sim/gpu-cache.cc | 29 ++++++++++++++++++++++++++--- src/gpgpu-sim/gpu-cache.h | 3 +++ src/gpgpu-sim/shader.cc | 5 +++-- 3 files changed, 32 insertions(+), 5 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 9e1db8b..390bacc 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1494,16 +1494,39 @@ 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 &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 + // Write allocate, maximum 2 requests (write miss, write back request) + // Conservatively ensure the worst-case request can be handled this + // cycle + if (m_config.m_write_policy == WRITE_THROUGH) { + bool mshr_hit = m_mshrs.probe(mshr_addr); + bool mshr_avail = !m_mshrs.full(mshr_addr); + if (miss_queue_full(1) || + (!(mshr_hit && mshr_avail) && + !(!mshr_hit && mshr_avail && + (m_miss_queue.size() < m_config.m_miss_queue_size)))) { + // check what is the exactly the failure reason + if (miss_queue_full(1)) + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + else if (mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + else if (!mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + else + assert(0); + + return RESERVATION_FAIL; + } + + send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); } + bool wb = false; evicted_block_info evicted; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index c2e302e..6811b86 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -821,6 +821,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() { diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 4b4c98d..22bd8e9 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1989,9 +1989,10 @@ void ldst_unit::L1_latency_queue_cycle() { } else { assert(status == MISS || status == HIT_RESERVED); l1_latency_queue[j][0] = NULL; - if (mf_next->get_inst().is_store() && + if (m_config->m_L1D_config.get_write_policy() != WRITE_THROUGH && + mf_next->get_inst().is_store() && (m_config->m_L1D_config.get_write_allocate_policy() == FETCH_ON_WRITE || - m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && + m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { unsigned dec_ack = (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC) -- cgit v1.3 From f7833519471ce92619bd1e4807ec07eb55aed76e Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 17 May 2021 17:35:06 -0400 Subject: new configs - adaptive cache and cache write ratio --- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 2 ++ configs/tested-cfgs/SM7_QV100/gpgpusim.config | 6 ++++++ configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 3 +++ src/abstract_hardware_model.h | 2 ++ src/gpgpu-sim/gpu-cache.h | 5 +++++ src/gpgpu-sim/gpu-sim.cc | 7 +++++++ 6 files changed, 25 insertions(+) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index 6189dca..e006085 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -110,6 +110,8 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_shmem_option 0,8,16,32,64,100 +-gpgpu_unified_l1d_size 128 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives us 3MB L2 cache -gpgpu_cache:dl2 S:64:128:16,L:B:m:L:P,A:192:4,32:0,32 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index bc5677c..043fce6 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -124,6 +124,9 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache -gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 @@ -203,3 +206,6 @@ #-trace_components WARP_SCHEDULER,SCOREBOARD #-trace_sampling_core 0 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 \ No newline at end of file diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 3fa51ee..1f0c15f 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -125,6 +125,9 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 4.5MB L2 cache -gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 982e416..e796571 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -373,6 +373,8 @@ class core_config { } unsigned mem_warp_parts; mutable unsigned gpgpu_shmem_size; + char *gpgpu_shmem_option; + unsigned gpgpu_unified_l1d_size; unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 00c09ae..ccc935b 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -491,6 +491,7 @@ class cache_config { m_data_port_width = 0; m_set_index_function = LINEAR_SET_FUNCTION; m_is_streaming = false; + m_wr_percent = 0; } void init(char *config, FuncCache status) { cache_status = status; @@ -754,6 +755,10 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; + unsigned m_wr_percent; + write_allocate_policy_t get_write_allocate_policy() { + return m_write_alloc_policy; + } protected: void exit_parse_error() { diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index fd36e00..bd09cdb 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -249,6 +249,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); + option_parser_register(opp,"-gpgpu_cache_write_ratio",OPT_UINT32,&m_L1D_config.m_wr_percent,"L1D write ratio","0"); option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, "The number of L1 cache banks", "1"); @@ -326,6 +327,12 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register( opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size, "Size of shared memory per shader core (default 16kB)", "16384"); + option_parser_register( + opp, "-gpgpu_shmem_option", OPT_CSTR, &gpgpu_shmem_option, + "Option list of shared memory sizes", "0"); + option_parser_register( + opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &gpgpu_unified_l1d_size, + "Size of unified data cache(L1D + shared memory) in KB", "0"); option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_BOOL, &adaptive_cache_config, "adaptive_cache_config", "0"); option_parser_register( -- cgit v1.3 From a2b1b1c2839fe3fc05a0cae126204120fab00f62 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 17 May 2021 17:35:53 -0400 Subject: adaptive cache - update --- src/abstract_hardware_model.h | 2 +- src/gpgpu-sim/gpu-cache.h | 11 +++++ src/gpgpu-sim/shader.cc | 95 +++++++++++++++++++++++++------------------ 3 files changed, 68 insertions(+), 40 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index e796571..bd10a93 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -65,7 +65,7 @@ enum FuncCache { FuncCachePreferL1 = 2 }; -enum AdaptiveCache { FIXED = 0, ADAPTIVE_VOLTA = 1 }; +enum AdaptiveCache { FIXED = 0, ADAPTIVE_CACHE = 1 }; #ifdef __cplusplus diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index ccc935b..0162b6c 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -616,6 +616,8 @@ class cache_config { m_atom_sz = (m_cache_type == SECTOR) ? SECTOR_SIZE : m_line_sz; m_sector_sz_log2 = LOGB2(SECTOR_SIZE); original_m_assoc = m_assoc; + original_sz = m_nset * original_m_assoc * m_line_sz; + // For more details about difference between FETCH_ON_WRITE and WRITE // VALIDAE policies Read: Jouppi, Norman P. "Cache write policies and @@ -710,6 +712,14 @@ class cache_config { assert(m_valid); return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc; } + unsigned get_original_assoc() const { + assert(m_valid); + return original_m_assoc; + } + unsigned get_original_sz() const { + assert(m_valid); + return original_sz; + } void print(FILE *fp) const { fprintf(fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", m_line_sz * m_nset * m_assoc, m_nset, m_assoc, m_line_sz); @@ -777,6 +787,7 @@ class cache_config { unsigned m_atom_sz; unsigned m_sector_sz_log2; unsigned original_m_assoc; + unsigned original_sz; bool m_is_streaming; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 14d9044..b2adb4f 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3292,50 +3292,67 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { if (adaptive_cache_config && !k.cache_config_set) { // For more info about adaptive cache, see // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x - unsigned total_shmed = kernel_info->smem * result; - assert(total_shmed >= 0 && total_shmed <= gpgpu_shmem_size); - // assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared - // assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets - if (total_shmed < gpgpu_shmem_size) { - switch (adaptive_cache_config) { - case FIXED: - break; - case ADAPTIVE_VOLTA: { - // For Volta, we assign the remaining shared memory to L1 cache - // For more info about adaptive cache, see - // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x - // assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared - - // To Do: make it flexible and not tuned to 9KB share memory - unsigned max_assoc = m_L1D_config.get_max_assoc(); - if (total_shmed == 0) - m_L1D_config.set_assoc(max_assoc); // L1 is 128KB and shd=0 - else if (total_shmed > 0 && total_shmed <= 8192) - m_L1D_config.set_assoc(0.9375 * - max_assoc); // L1 is 120KB and shd=8KB - else if (total_shmed > 8192 && total_shmed <= 16384) - m_L1D_config.set_assoc(0.875 * - max_assoc); // L1 is 112KB and shd=16KB - else if (total_shmed > 16384 && total_shmed <= 32768) - m_L1D_config.set_assoc(0.75 * max_assoc); // L1 is 96KB and - // shd=32KB - else if (total_shmed > 32768 && total_shmed <= 65536) - m_L1D_config.set_assoc(0.5 * max_assoc); // L1 is 64KB and shd=64KB - else if (total_shmed > 65536 && total_shmed <= gpgpu_shmem_size) - m_L1D_config.set_assoc(0.25 * max_assoc); // L1 is 32KB and - // shd=96KB - else - assert(0); - break; + std::vector shmem_list; + for (unsigned i = 0; i < strlen(gpgpu_shmem_option); i++) { + char option[4]; + int j = 0; + while (gpgpu_shmem_option[i] != ',' && i < strlen(gpgpu_shmem_option)) { + if (gpgpu_shmem_option[i] == ' ') { + // skip spaces + i++; + } else { + if (!isdigit(gpgpu_shmem_option[i])) { + // check for non digits, which should not be here + assert(0 && "invalid config: -gpgpu_shmem_option"); + } + option[j] = gpgpu_shmem_option[i]; + j++; + i++; } - default: - assert(0); } + // convert KB -> B + shmem_list.push_back((unsigned)atoi(option) * 1024); + } - printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", - m_L1D_config.get_total_size_inKB()); + unsigned total_shmem = kernel_info->smem * result; + unsigned total_unified = gpgpu_unified_l1d_size * 1024; + std::sort(shmem_list.begin(), shmem_list.end()); + + assert(total_shmem >= 0 && total_shmem <= shmem_list.back()); + switch (adaptive_cache_config) { + case FIXED: + break; + case ADAPTIVE_CACHE: { + // For more info about adaptive cache, see + bool l1d_configured = false; + unsigned l1_defined = m_L1D_config.get_original_sz() / 1024; + unsigned max_assoc = m_L1D_config.get_original_assoc() * + gpgpu_unified_l1d_size / l1_defined; + + if (total_shmem == 0) { + m_L1D_config.set_assoc(max_assoc); + l1d_configured = true; + } else { + for (std::vector::iterator it = shmem_list.begin(); + it < shmem_list.end() - 1; it++) { + if (total_shmem > *it && total_shmem <= *(it + 1)) { + float l1_ratio = 1 - (float) *(it + 1) / total_unified; + m_L1D_config.set_assoc(max_assoc * l1_ratio); + l1d_configured = true; + break; + } + } + } + assert(l1d_configured && "no shared memory option found"); + break; + } + default: + assert(0); } + printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", + m_L1D_config.get_total_size_inKB()); + k.cache_config_set = true; } -- cgit v1.3 From f70f5d6e5599c643074b0d00d3e3dcc385e5913d Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 15:10:51 -0400 Subject: re-wording/formatting --- src/gpgpu-sim/gpu-cache.cc | 17 ++++++++--------- src/gpgpu-sim/gpu-cache.h | 6 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 390bacc..05b338e 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -280,7 +280,7 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, } if (!line->is_reserved_line()) { if (!line->is_modified_line() || - 100 * m_dirty / (m_config.m_nset * m_config.m_assoc) >= + m_dirty / (m_config.m_nset * m_config.m_assoc * 100) >= m_config.m_wr_percent) { all_reserved = false; if (line->is_invalid_line()) { @@ -364,7 +364,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, evicted.set_info(m_lines[idx]->m_block_addr, m_lines[idx]->get_modified_size(), m_lines[idx]->get_byte_mask(), - m_lines[idx]->get_sector_mask()); + m_lines[idx]->get_dirty_sector_mask()); m_dirty--; } m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), @@ -430,17 +430,13 @@ void tag_array::fill(new_addr_type addr, unsigned time, void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) { assert(m_config.m_alloc_policy == ON_MISS); - 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++; - } + m_dirty++; } // TODO: we need write back the flushed data to the upper level void tag_array::flush() { if (!is_used) return; - m_dirty = 0; for (unsigned i = 0; i < m_config.get_num_lines(); i++) if (m_lines[i]->is_modified_line()) { @@ -448,18 +444,19 @@ void tag_array::flush() { m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); } } - + + m_dirty = 0; is_used = false; } void tag_array::invalidate() { if (!is_used) return; - m_dirty = 0; 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)); + m_dirty = 0; is_used = false; } @@ -804,6 +801,8 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const { m_stats[type][status]); 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]; } } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 6811b86..5179173 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -136,7 +136,7 @@ struct cache_block_t { 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_byte_mask() = 0; - virtual mem_access_sector_mask_t get_sector_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; @@ -218,7 +218,7 @@ struct line_cache_block : public cache_block_t { virtual mem_access_byte_mask_t get_byte_mask() { return m_byte_mask; } - virtual mem_access_sector_mask_t get_sector_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; @@ -413,7 +413,7 @@ struct sector_cache_block : public cache_block_t { virtual mem_access_byte_mask_t get_byte_mask() { return m_byte_mask; } - virtual mem_access_sector_mask_t get_sector_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) -- cgit v1.3 From 4c354ebda2c92bb5866c20f03a254743c8ec85a3 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 15:45:35 -0400 Subject: minor improvements --- src/gpgpu-sim/gpu-cache.cc | 14 ++++++++------ src/gpgpu-sim/gpu-cache.h | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 05b338e..98951ca 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -279,17 +279,19 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, } } if (!line->is_reserved_line()) { + // 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 (!line->is_modified_line() || - m_dirty / (m_config.m_nset * m_config.m_assoc * 100) >= - m_config.m_wr_percent) { + dirty_line_percentage >= m_config.m_wr_percent) { + // if number of dirty lines in the cache is greater than + // a specific value all_reserved = false; if (line->is_invalid_line()) { invalid_line = index; } else { // valid line : keep track of most appropriate replacement candidate - - // don't evict write until dirty lines reach threshold - // make sure at least 1 candidate is assigned if (m_config.m_replacement_policy == LRU) { if (line->get_last_access_time() < valid_timestamp) { valid_timestamp = line->get_last_access_time(); @@ -363,7 +365,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, 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_byte_mask(), + m_lines[idx]->get_dirty_byte_mask(), m_lines[idx]->get_dirty_sector_mask()); m_dirty--; } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 5179173..dc3b39a 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -135,7 +135,7 @@ struct cache_block_t { 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_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, @@ -215,7 +215,7 @@ struct line_cache_block : public cache_block_t { 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_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() { @@ -410,7 +410,7 @@ struct sector_cache_block : public cache_block_t { 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_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() { -- cgit v1.3 From f27da224f3e468d600499a9d3619009ed9c70256 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 17:27:43 -0400 Subject: Use cache config multipilier when possible --- src/abstract_hardware_model.h | 1 - src/gpgpu-sim/gpu-cache.h | 28 +++++++++++++++------------- src/gpgpu-sim/gpu-sim.cc | 2 +- src/gpgpu-sim/shader.cc | 8 +++----- 4 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index bd10a93..dbe138a 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -374,7 +374,6 @@ class core_config { unsigned mem_warp_parts; mutable unsigned gpgpu_shmem_size; char *gpgpu_shmem_option; - unsigned gpgpu_unified_l1d_size; unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 0162b6c..87a6b13 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -512,6 +512,14 @@ class cache_config { exit_parse_error(); } + // set * assoc * cacheline size. Then convert Byte to KB + unsigned original_size = m_nset * m_assoc * m_line_sz / 1024; + if (m_unified_cache_size > 0) { + max_cache_multiplier = m_unified_cache_size / original_size; + } else { + max_cache_multiplier = MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; + } + switch (ct) { case 'N': m_cache_type = NORMAL; @@ -588,7 +596,7 @@ class cache_config { // 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; + m_mshr_entries = m_nset * m_assoc * max_cache_multiplier; if (m_cache_type == SECTOR) m_mshr_entries *= SECTOR_CHUNCK_SIZE; m_mshr_max_merge = MAX_WARP_PER_SM; } @@ -616,7 +624,6 @@ class cache_config { m_atom_sz = (m_cache_type == SECTOR) ? SECTOR_SIZE : m_line_sz; m_sector_sz_log2 = LOGB2(SECTOR_SIZE); original_m_assoc = m_assoc; - original_sz = m_nset * original_m_assoc * m_line_sz; // For more details about difference between FETCH_ON_WRITE and WRITE @@ -706,19 +713,13 @@ class cache_config { } unsigned get_max_num_lines() const { assert(m_valid); - return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * m_nset * original_m_assoc; + // gpgpu_unified_cache_size is in KB while original_sz is in B + return max_cache_multiplier * m_nset * original_m_assoc; } unsigned get_max_assoc() const { assert(m_valid); - return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc; - } - unsigned get_original_assoc() const { - assert(m_valid); - return original_m_assoc; - } - unsigned get_original_sz() const { - assert(m_valid); - return original_sz; + // gpgpu_unified_cache_size is in KB while original_sz is in B + return max_cache_multiplier * original_m_assoc; } void print(FILE *fp) const { fprintf(fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", @@ -766,6 +767,7 @@ class cache_config { char *m_config_stringPrefShared; FuncCache cache_status; unsigned m_wr_percent; + unsigned m_unified_cache_size; write_allocate_policy_t get_write_allocate_policy() { return m_write_alloc_policy; } @@ -787,8 +789,8 @@ class cache_config { unsigned m_atom_sz; unsigned m_sector_sz_log2; unsigned original_m_assoc; - unsigned original_sz; bool m_is_streaming; + unsigned max_cache_multiplier; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO enum write_policy_t diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a2aa929..df30047 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -331,7 +331,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { opp, "-gpgpu_shmem_option", OPT_CSTR, &gpgpu_shmem_option, "Option list of shared memory sizes", "0"); option_parser_register( - opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &gpgpu_unified_l1d_size, + opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &m_L1D_config.m_unified_cache_size, "Size of unified data cache(L1D + shared memory) in KB", "0"); option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_BOOL, &adaptive_cache_config, "adaptive_cache_config", "0"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 141c700..3efef2b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3315,7 +3315,8 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { } unsigned total_shmem = kernel_info->smem * result; - unsigned total_unified = gpgpu_unified_l1d_size * 1024; + // Unified cache config is in KB. Converting to B + unsigned total_unified = m_L1D_config.m_unified_cache_size * 1024; std::sort(shmem_list.begin(), shmem_list.end()); assert(total_shmem >= 0 && total_shmem <= shmem_list.back()); @@ -3325,10 +3326,7 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { case ADAPTIVE_CACHE: { // For more info about adaptive cache, see bool l1d_configured = false; - unsigned l1_defined = m_L1D_config.get_original_sz() / 1024; - assert(gpgpu_unified_l1d_size % l1_defined == 0); - unsigned max_assoc = m_L1D_config.get_original_assoc() * - gpgpu_unified_l1d_size / l1_defined; + unsigned max_assoc = m_L1D_config.get_max_assoc(); if (total_shmem == 0) { m_L1D_config.set_assoc(max_assoc); -- cgit v1.3 From 604baaf59255776b4714c0270ce36ad823d34df4 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Wed, 19 May 2021 18:28:41 -0400 Subject: fixing the failing of merging --- src/gpgpu-sim/gpu-cache.h | 3 +-- src/gpgpu-sim/shader.cc | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 75dce40..d801528 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -841,8 +841,8 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; - unsigned m_wr_percent; unsigned m_unified_cache_size; + unsigned m_wr_percent; write_allocate_policy_t get_write_allocate_policy() { return m_write_alloc_policy; } @@ -897,7 +897,6 @@ 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; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index db53fca..75fbe16 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3391,13 +3391,12 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { assert(0); } -<<<<<<< HEAD if(m_L1D_config.is_streaming()) { //for streaming cache, if the whole memory is allocated //to the L1 cache, then make the allocation to be on_MISS //otherwise, make it ON_FILL to eliminate line allocation fails //i.e. MSHR throughput is the same, independent on the L1 cache size/associativity - if(total_shmed == 0) { + if(total_shmem == 0) { m_L1D_config.set_allocation_policy(ON_MISS); printf("GPGPU-Sim: Reconfigure L1 allocation to ON_MISS\n"); } @@ -3406,10 +3405,8 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { printf("GPGPU-Sim: Reconfigure L1 allocation to ON_FILL\n"); } } -======= printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", m_L1D_config.get_total_size_inKB()); ->>>>>>> 2b2b6a2916e4ed833c707be887bf927167a71fa6 k.cache_config_set = true; } -- cgit v1.3 From 24ffab25f41d76b94fd2012a8897312a73a7165f Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Wed, 19 May 2021 21:17:40 -0400 Subject: moving shmem option to the base class and change the code to accept turing config --- src/abstract_hardware_model.h | 1 + src/gpgpu-sim/gpu-cache.h | 3 +-- src/gpgpu-sim/shader.cc | 46 +++++++++---------------------------------- src/gpgpu-sim/shader.h | 26 ++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 39 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 17a1cec..b33c50b 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -374,6 +374,7 @@ class core_config { unsigned mem_warp_parts; mutable unsigned gpgpu_shmem_size; char *gpgpu_shmem_option; + std::vector shmem_opt_list; unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index d801528..26ed621 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -577,6 +577,7 @@ class cache_config { } // set * assoc * cacheline size. Then convert Byte to KB + // gpgpu_unified_cache_size is in KB while original_sz is in B unsigned original_size = m_nset * m_assoc * m_line_sz / 1024; if (m_unified_cache_size > 0) { max_cache_multiplier = m_unified_cache_size / original_size; @@ -785,12 +786,10 @@ class cache_config { } unsigned get_max_num_lines() const { assert(m_valid); - // gpgpu_unified_cache_size is in KB while original_sz is in B return max_cache_multiplier * m_nset * original_m_assoc; } unsigned get_max_assoc() const { assert(m_valid); - // gpgpu_unified_cache_size is in KB while original_sz is in B return max_cache_multiplier * original_m_assoc; } void print(FILE *fp) const { diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 75fbe16..bc747d6 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3334,56 +3334,28 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { if (adaptive_cache_config && !k.cache_config_set) { // For more info about adaptive cache, see // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x - std::vector shmem_list; - for (unsigned i = 0; i < strlen(gpgpu_shmem_option); i++) { - char option[4]; - int j = 0; - while (gpgpu_shmem_option[i] != ',' && i < strlen(gpgpu_shmem_option)) { - if (gpgpu_shmem_option[i] == ' ') { - // skip spaces - i++; - } else { - if (!isdigit(gpgpu_shmem_option[i])) { - // check for non digits, which should not be here - assert(0 && "invalid config: -gpgpu_shmem_option"); - } - option[j] = gpgpu_shmem_option[i]; - j++; - i++; - } - } - // convert KB -> B - shmem_list.push_back((unsigned)atoi(option) * 1024); - } - unsigned total_shmem = kernel_info->smem * result; // Unified cache config is in KB. Converting to B unsigned total_unified = m_L1D_config.m_unified_cache_size * 1024; - std::sort(shmem_list.begin(), shmem_list.end()); - assert(total_shmem >= 0 && total_shmem <= shmem_list.back()); + assert(total_shmem >= 0 && total_shmem <= shmem_opt_list.back()); switch (adaptive_cache_config) { case FIXED: break; case ADAPTIVE_CACHE: { - // For more info about adaptive cache, see bool l1d_configured = false; unsigned max_assoc = m_L1D_config.get_max_assoc(); - if (total_shmem == 0) { - m_L1D_config.set_assoc(max_assoc); - l1d_configured = true; - } else { - for (std::vector::iterator it = shmem_list.begin(); - it < shmem_list.end() - 1; it++) { - if (total_shmem > *it && total_shmem <= *(it + 1)) { - float l1_ratio = 1 - (float) *(it + 1) / total_unified; - m_L1D_config.set_assoc(max_assoc * l1_ratio); - l1d_configured = true; - break; - } + for (std::vector::const_iterator it = shmem_opt_list.begin(); + it < shmem_opt_list.end(); it++) { + if (total_shmem <= *it) { + float l1_ratio = 1 - ((float) *(it) / total_unified); + m_L1D_config.set_assoc(max_assoc * l1_ratio); + l1d_configured = true; + break; } } + assert(l1d_configured && "no shared memory option found"); break; } diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index a7a2c02..42bbdcb 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1495,6 +1495,32 @@ class shader_core_config : public core_config { } else break; // we only accept continuous specialized_units, i.e., 1,2,3,4 } + + //parse gpgpu_shmem_option for adpative cache config + if(adaptive_cache_config) { + for (unsigned i = 0; i < strlen(gpgpu_shmem_option); i++) { + char option[4]; + int j = 0; + while (gpgpu_shmem_option[i] != ',' && i < strlen(gpgpu_shmem_option)) { + if (gpgpu_shmem_option[i] == ' ') { + // skip spaces + i++; + } else { + if (!isdigit(gpgpu_shmem_option[i])) { + // check for non digits, which should not be here + assert(0 && "invalid config: -gpgpu_shmem_option"); + } + option[j] = gpgpu_shmem_option[i]; + j++; + i++; + } + } + // convert KB -> B + shmem_opt_list.push_back((unsigned)atoi(option) * 1024); + } + std::sort(shmem_opt_list.begin(), shmem_opt_list.end()); + } + } void reg_options(class OptionParser *opp); unsigned max_cta(const kernel_info_t &k) const; -- cgit v1.3 From fedcde3789f7921647caee184c0fa104403c848d Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Wed, 19 May 2021 21:42:29 -0400 Subject: moving the unified size from the base class config to l1 config --- src/gpgpu-sim/gpu-cache.h | 30 ++++++++++++++++-------------- src/gpgpu-sim/shader.cc | 3 ++- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 26ed621..8bd62da 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -575,15 +575,6 @@ class cache_config { } exit_parse_error(); } - - // set * assoc * cacheline size. Then convert Byte to KB - // gpgpu_unified_cache_size is in KB while original_sz is in B - unsigned original_size = m_nset * m_assoc * m_line_sz / 1024; - if (m_unified_cache_size > 0) { - max_cache_multiplier = m_unified_cache_size / original_size; - } else { - max_cache_multiplier = MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; - } switch (ct) { case 'N': @@ -694,7 +685,6 @@ class cache_config { m_sector_sz_log2 = LOGB2(SECTOR_SIZE); original_m_assoc = m_assoc; - // For more details about difference between FETCH_ON_WRITE and WRITE // VALIDAE policies Read: Jouppi, Norman P. "Cache write policies and // performance". ISCA 93. WRITE_ALLOCATE is the old write policy in @@ -786,11 +776,11 @@ class cache_config { } unsigned get_max_num_lines() const { assert(m_valid); - return max_cache_multiplier * m_nset * original_m_assoc; + return get_max_cache_multiplier() * m_nset * original_m_assoc; } unsigned get_max_assoc() const { assert(m_valid); - return max_cache_multiplier * original_m_assoc; + return get_max_cache_multiplier() * original_m_assoc; } void print(FILE *fp) const { fprintf(fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", @@ -799,6 +789,8 @@ class cache_config { virtual unsigned set_index(new_addr_type addr) const; + virtual unsigned get_max_cache_multiplier() const { return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER;} + unsigned hash_function(new_addr_type addr, unsigned m_nset, unsigned m_line_sz_log2, unsigned m_nset_log2, unsigned m_index_function) const; @@ -840,7 +832,6 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; - unsigned m_unified_cache_size; unsigned m_wr_percent; write_allocate_policy_t get_write_allocate_policy() { return m_write_alloc_policy; @@ -867,7 +858,6 @@ class cache_config { unsigned m_sector_sz_log2; unsigned original_m_assoc; bool m_is_streaming; - unsigned max_cache_multiplier; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO enum write_policy_t @@ -922,6 +912,18 @@ class l1d_cache_config : public cache_config { unsigned l1_banks_byte_interleaving; unsigned l1_banks_byte_interleaving_log2; unsigned l1_banks_hashing_function; + unsigned m_unified_cache_size; + virtual unsigned get_max_cache_multiplier() const { + // set * assoc * cacheline size. Then convert Byte to KB + // gpgpu_unified_cache_size is in KB while original_sz is in B + if (m_unified_cache_size > 0) { + unsigned original_size = m_nset * original_m_assoc * m_line_sz / 1024; + assert(m_unified_cache_size % original_size == 0); + return m_unified_cache_size / original_size; + } else { + return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; + } + } }; class l2_cache_config : public cache_config { diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index bc747d6..7f27b7b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3335,10 +3335,11 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { // For more info about adaptive cache, see // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x unsigned total_shmem = kernel_info->smem * result; + assert(total_shmem >= 0 && total_shmem <= shmem_opt_list.back()); + // Unified cache config is in KB. Converting to B unsigned total_unified = m_L1D_config.m_unified_cache_size * 1024; - assert(total_shmem >= 0 && total_shmem <= shmem_opt_list.back()); switch (adaptive_cache_config) { case FIXED: break; -- cgit v1.3 From 8aee56d7401af9a91a1de3adae1b61329e0d30e5 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Wed, 19 May 2021 22:10:53 -0400 Subject: rename set_dirty_byte_mask --- src/gpgpu-sim/gpu-cache.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 8bd62da..91cde7e 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -210,13 +210,13 @@ struct line_cache_block : public cache_block_t { m_status = status; } virtual void set_byte_mask(mem_fetch *mf) { - m_byte_mask = m_byte_mask | mf->get_access_byte_mask(); + m_dirty_byte_mask = m_dirty_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; + m_dirty_byte_mask = m_dirty_byte_mask | byte_mask; } virtual mem_access_byte_mask_t get_dirty_byte_mask() { - return m_byte_mask; + return m_dirty_byte_mask; } virtual mem_access_sector_mask_t get_dirty_sector_mask() { mem_access_sector_mask_t sector_mask; @@ -270,7 +270,7 @@ struct line_cache_block : public cache_block_t { bool m_set_readable_on_fill; bool m_set_byte_mask_on_fill; bool m_readable; - mem_access_byte_mask_t m_byte_mask; + mem_access_byte_mask_t m_dirty_byte_mask; }; struct sector_cache_block : public cache_block_t { @@ -290,7 +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(); + m_dirty_byte_mask.reset(); } virtual void allocate(new_addr_type tag, new_addr_type block_addr, @@ -405,13 +405,13 @@ struct sector_cache_block : public cache_block_t { } virtual void set_byte_mask(mem_fetch *mf) { - m_byte_mask = m_byte_mask | mf->get_access_byte_mask(); + m_dirty_byte_mask = m_dirty_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; + m_dirty_byte_mask = m_dirty_byte_mask | byte_mask; } virtual mem_access_byte_mask_t get_dirty_byte_mask() { - return m_byte_mask; + return m_dirty_byte_mask; } virtual mem_access_sector_mask_t get_dirty_sector_mask() { mem_access_sector_mask_t sector_mask; @@ -492,7 +492,7 @@ struct sector_cache_block : public cache_block_t { 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; + mem_access_byte_mask_t m_dirty_byte_mask; unsigned get_sector_index(mem_access_sector_mask_t sector_mask) { assert(sector_mask.count() == 1); -- cgit v1.3 From b466afea67e6d6faf49f01ecfe378257fbdb93af Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Wed, 19 May 2021 22:20:04 -0400 Subject: eliminate redundant code in gpu-cache.h --- src/gpgpu-sim/gpu-cache.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 91cde7e..6698d92 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -596,16 +596,6 @@ class cache_config { default: exit_parse_error(); } - switch (rp) { - case 'L': - m_replacement_policy = LRU; - break; - case 'F': - m_replacement_policy = FIFO; - break; - default: - exit_parse_error(); - } switch (wp) { case 'R': m_write_policy = READ_ONLY; -- cgit v1.3 From c8eca04403d3acaff413788e342fd6aadd122948 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 17 May 2021 17:35:06 -0400 Subject: fix merge conflict --- src/gpgpu-sim/gpu-cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 6698d92..007403f 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -563,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,%u", &ct, + sscanf(config, "%c:%u:%u:%u,%c:%c:%c:%c:%c,%c:%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_wr_percent); + &m_miss_queue_size, &m_result_fifo_entries, &m_data_port_width); if (ntok < 12) { if (!strcmp(config, "none")) { -- cgit v1.3 From 6c9e13db93e4a1614f7401e9675c62ea40b65a3b Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Sun, 23 May 2021 12:59:34 -0400 Subject: format code --- src/abstract_hardware_model.cc | 12 +++-- src/abstract_hardware_model.h | 13 +++-- src/cuda-sim/instructions.cc | 99 ++++++++++++++++++---------------- src/cuda-sim/ptx_ir.cc | 4 +- src/cuda-sim/ptx_ir.h | 4 +- src/cuda-sim/ptx_parser.cc | 14 ++--- src/gpgpu-sim/gpu-cache.cc | 89 +++++++++++++++--------------- src/gpgpu-sim/gpu-cache.h | 84 ++++++++++++++--------------- src/gpgpu-sim/gpu-sim.cc | 12 +++-- src/gpgpu-sim/l2cache.cc | 57 ++++++++++---------- src/gpgpu-sim/l2cache.h | 13 +++-- src/gpgpu-sim/shader.cc | 119 +++++++++++++++++++++-------------------- src/gpgpu-sim/shader.h | 17 +++--- 13 files changed, 273 insertions(+), 264 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index e0e1d23..30aee60 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -448,7 +448,8 @@ void warp_inst_t::generate_mem_accesses() { for (unsigned thread = 0; thread < m_config->warp_size; thread++) { if (!active(thread)) continue; new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[0]; - new_addr_type block_address = line_size_based_tag_func(addr, cache_block_size); + new_addr_type block_address = + line_size_based_tag_func(addr, cache_block_size); accesses[block_address].set(thread); unsigned idx = addr - block_address; for (unsigned i = 0; i < data_size; i++) byte_mask.set(idx + i); @@ -530,7 +531,8 @@ void warp_inst_t::memory_coalescing_arch(bool is_write, (m_per_scalar_thread[thread].memreqaddr[access] != 0); access++) { new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[access]; - new_addr_type block_address = line_size_based_tag_func(addr, segment_size); + new_addr_type block_address = + line_size_based_tag_func(addr, segment_size); unsigned chunk = (addr & 127) / 32; // which 32-byte chunk within in a 128-byte // chunk does this thread access? @@ -552,7 +554,8 @@ void warp_inst_t::memory_coalescing_arch(bool is_write, if (block_address != line_size_based_tag_func( addr + data_size_coales - 1, segment_size)) { addr = addr + data_size_coales - 1; - new_addr_type block_address = line_size_based_tag_func(addr, segment_size); + new_addr_type block_address = + line_size_based_tag_func(addr, segment_size); unsigned chunk = (addr & 127) / 32; transaction_info &info = subwarp_transactions[block_address]; info.chunks.set(chunk); @@ -625,7 +628,8 @@ void warp_inst_t::memory_coalescing_arch_atomic(bool is_write, if (!active(thread)) continue; new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[0]; - new_addr_type block_address = line_size_based_tag_func(addr, segment_size); + new_addr_type block_address = + line_size_based_tag_func(addr, segment_size); unsigned chunk = (addr & 127) / 32; // which 32-byte chunk within in a 128-byte chunk // does this thread access? diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 60d7328..35e28ca 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -872,13 +872,12 @@ class mem_fetch_allocator { const mem_access_t &access, unsigned long long cycle) const = 0; virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, - const active_mask_t &active_mask, - const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask, - unsigned size, bool wr, - unsigned long long cycle, - unsigned wid, unsigned sid, - unsigned tpc, mem_fetch *original_mf) const = 0; + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, unsigned long long cycle, + unsigned wid, unsigned sid, unsigned tpc, + mem_fetch *original_mf) const = 0; }; // the maximum number of destination, source, or address uarch operands in a diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 8936fa8..0b990e8 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -166,8 +166,9 @@ void inst_not_implemented(const ptx_instruction *pI); ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, operand_info dstInfo, unsigned type, ptx_thread_info *thread); - -void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code); + +void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, + int op_code); void sign_extend(ptx_reg_t &data, unsigned src_size, const operand_info &dst); @@ -1711,40 +1712,50 @@ void bfi_impl(const ptx_instruction *pI, ptx_thread_info *thread) { } thread->set_operand_value(dst, data, i_type, thread, pI); } -void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) -{ - const operand_info &dst = pI->dst(); +void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) { + const operand_info &dst = pI->dst(); const operand_info &src1 = pI->src1(); const unsigned i_type = pI->get_type(); - const ptx_reg_t src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1); - const int msb = ( i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63; + const ptx_reg_t src1_data = + thread->get_operand_value(src1, dst, i_type, thread, 1); + const int msb = (i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63; unsigned long a = 0; - switch (i_type) - { - case S32_TYPE: a = src1_data.s32; break; - case U32_TYPE: a = src1_data.u32; break; - case S64_TYPE: a = src1_data.s64; break; - case U64_TYPE: a = src1_data.u64; break; - default: assert(false); abort(); + switch (i_type) { + case S32_TYPE: + a = src1_data.s32; + break; + case U32_TYPE: + a = src1_data.u32; + break; + case S64_TYPE: + a = src1_data.s64; + break; + case U64_TYPE: + a = src1_data.u64; + break; + default: + assert(false); + abort(); } // negate negative signed inputs - if ( ( i_type == S32_TYPE || i_type == S64_TYPE ) && ( a & ( 1 << msb ) ) ) { - a = ~a; + if ((i_type == S32_TYPE || i_type == S64_TYPE) && (a & (1 << msb))) { + a = ~a; } uint32_t d_data = 0xffffffff; for (uint32_t i = msb; i >= 0; i--) { - if (a & (1<set_operand_value(dst, d_data, U32_TYPE, thread, pI); - - } void bra_impl(const ptx_instruction *pI, ptx_thread_info *thread) { @@ -6339,12 +6350,10 @@ void vmad_impl(const ptx_instruction *pI, ptx_thread_info *thread) { #define VMAX 0 #define VMIN 1 -void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) -{ - video_mem_instruction(pI, thread, VMAX); +void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) { + video_mem_instruction(pI, thread, VMAX); } -void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) -{ +void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) { video_mem_instruction(pI, thread, VMIN); } void vset_impl(const ptx_instruction *pI, ptx_thread_info *thread) { @@ -6440,12 +6449,12 @@ void vote_impl(const ptx_instruction *pI, ptx_thread_info *thread) { } } -void activemask_impl( const ptx_instruction *pI, ptx_thread_info *thread ) -{ +void activemask_impl(const ptx_instruction *pI, ptx_thread_info *thread) { active_mask_t l_activemask_bitset = pI->get_warp_active_mask(); - uint32_t l_activemask_uint = static_cast(l_activemask_bitset.to_ulong()); + uint32_t l_activemask_uint = + static_cast(l_activemask_bitset.to_ulong()); - const operand_info &dst = pI->dst(); + const operand_info &dst = pI->dst(); thread->set_operand_value(dst, l_activemask_uint, U32_TYPE, thread, pI); } @@ -6527,12 +6536,12 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, return result; } -void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code) -{ - const operand_info &dst = pI->dst(); // d - const operand_info &src1 = pI->src1(); // a - const operand_info &src2 = pI->src2(); // b - const operand_info &src3 = pI->src3(); // c +void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, + int op_code) { + const operand_info &dst = pI->dst(); // d + const operand_info &src1 = pI->src1(); // a + const operand_info &src2 = pI->src2(); // b + const operand_info &src3 = pI->src3(); // c const unsigned i_type = pI->get_type(); @@ -6557,19 +6566,18 @@ void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, i auto option = options.begin(); assert(*option == ATOMIC_MAX || *option == ATOMIC_MIN); - switch ( i_type ) { + switch (i_type) { case S32_TYPE: { // assert all operands are S32_TYPE: scalar_type = pI->get_scalar_type(); - for (std::list::iterator scalar = scalar_type.begin(); scalar != scalar_type.end(); scalar++) - { + for (std::list::iterator scalar = scalar_type.begin(); + scalar != scalar_type.end(); scalar++) { assert(*scalar == S32_TYPE); } assert(scalar_type.size() == 3); scalar_type.clear(); - switch (op_code) - { + switch (op_code) { case VMAX: data.s32 = MY_MAX_I(ta.s32, tb.s32); break; @@ -6580,26 +6588,23 @@ void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, i assert(0); } - switch (*option) - { + switch (*option) { case ATOMIC_MAX: data.s32 = MY_MAX_I(data.s32, c.s32); - break; + break; case ATOMIC_MIN: data.s32 = MY_MIN_I(data.s32, c.s32); - break; + break; default: - assert(0); // not yet implemented + assert(0); // not yet implemented } break; - } default: - assert(0); // not yet implemented + assert(0); // not yet implemented } thread->set_operand_value(dst, data, i_type, thread, pI); return; } - diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index e5b5fb7..d3da4b5 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -1147,8 +1147,8 @@ static std::list check_operands( const std::list &operands, gpgpu_context *ctx) { static int g_warn_literal_operands_two_type_inst; if ((opcode == CVT_OP) || (opcode == SET_OP) || (opcode == SLCT_OP) || - (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP) || - (opcode == VMIN_OP) || (opcode == VMAX_OP) ) { + (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP) || + (opcode == VMIN_OP) || (opcode == VMAX_OP)) { // just make sure these do not have have const operands... if (!g_warn_literal_operands_two_type_inst) { std::list::const_iterator o; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 4243941..8251759 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -966,8 +966,8 @@ class ptx_instruction : public warp_inst_t { int get_pred_mod() const { return m_pred_mod; } const char *get_source() const { return m_source.c_str(); } - const std::list get_scalar_type() const {return m_scalar_type;} - const std::list get_options() const {return m_options;} + const std::list get_scalar_type() const { return m_scalar_type; } + const std::list get_options() const { return m_options; } typedef std::vector::const_iterator const_iterator; diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index afdb41b..86a33c2 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -622,13 +622,13 @@ void ptx_recognizer::add_scalar_type_spec(int type_spec) { g_ptx_token_decode[type_spec].c_str()); g_scalar_type.push_back(type_spec); if (g_scalar_type.size() > 1) { - parse_assert((g_opcode == -1) || (g_opcode == CVT_OP) || - (g_opcode == SET_OP) || (g_opcode == SLCT_OP) || - (g_opcode == TEX_OP) || (g_opcode == MMA_OP) || - (g_opcode == DP4A_OP) || (g_opcode == VMIN_OP) || - (g_opcode == VMAX_OP), - "only cvt, set, slct, tex, vmin, vmax and dp4a can have more than one " - "type specifier."); + parse_assert( + (g_opcode == -1) || (g_opcode == CVT_OP) || (g_opcode == SET_OP) || + (g_opcode == SLCT_OP) || (g_opcode == TEX_OP) || + (g_opcode == MMA_OP) || (g_opcode == DP4A_OP) || + (g_opcode == VMIN_OP) || (g_opcode == VMAX_OP), + "only cvt, set, slct, tex, vmin, vmax and dp4a can have more than one " + "type specifier."); } g_scalar_type_spec = type_spec; } diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 7e7d2ad..28d3215 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -37,7 +37,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", "MSHR_HIT"}; + "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 +64,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_log2, - 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 { @@ -235,7 +236,7 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, 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,is_write, 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, @@ -281,8 +282,8 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, if (!line->is_reserved_line()) { // 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; + float dirty_line_percentage = + ((float)m_dirty / (m_config.m_nset * m_config.m_assoc)) * 100; if (!line->is_modified_line() || dirty_line_percentage >= m_config.m_wr_percent) { // if number of dirty lines in the cache is greater than @@ -357,7 +358,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, evicted.set_info(m_lines[idx]->m_block_addr, m_lines[idx]->get_modified_size(), m_lines[idx]->get_dirty_byte_mask(), - m_lines[idx]->get_dirty_sector_mask()); + m_lines[idx]->get_dirty_sector_mask()); m_dirty--; } m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), @@ -372,9 +373,9 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, 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--; - } + if (before && !m_lines[idx]->is_modified_line()) { + m_dirty--; + } } break; case RESERVATION_FAIL: @@ -391,16 +392,18 @@ 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, 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_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_byte_mask_t byte_mask, - bool is_write) { + 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,is_write); + 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 @@ -423,7 +426,8 @@ void tag_array::fill(new_addr_type addr, unsigned time, 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(), mf->get_access_byte_mask()); + m_lines[index]->fill(time, mf->get_access_sector_mask(), + mf->get_access_byte_mask()); m_dirty++; } @@ -437,7 +441,7 @@ void tag_array::flush() { m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); } } - + m_dirty = 0; is_used = false; } @@ -794,8 +798,8 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const { m_stats[type][status]); if (status != RESERVATION_FAIL && status != MSHR_HIT) - // MSHR_HIT is a special type of SECTOR_MISS - // so its already included in the SECTOR_MISS + // MSHR_HIT is a special type of SECTOR_MISS + // so its already included in the SECTOR_MISS total_access[type] += m_stats[type][status]; } } @@ -1335,10 +1339,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, - 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); + 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); @@ -1388,10 +1392,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, - 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); + 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); @@ -1461,10 +1465,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, - 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); + 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); @@ -1514,7 +1518,6 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); } - bool wb = false; evicted_block_info evicted; @@ -1538,7 +1541,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( } 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()); + block->set_readable_on_fill(true, mf->get_access_sector_mask()); } if (m_status != RESERVATION_FAIL) { @@ -1546,10 +1549,10 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( // (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, - 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); + 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); @@ -1596,7 +1599,7 @@ enum cache_request_status data_cache::rd_hit_base( m_tag_array->inc_dirty(); } block->set_status(MODIFIED, - mf->get_access_sector_mask()); // mark line as + mf->get_access_sector_mask()); // mark line as block->set_byte_mask(mf); } return HIT; @@ -1628,10 +1631,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, - 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); + 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); diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 007403f..7a2a8d9 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -84,7 +84,7 @@ struct evicted_block_info { m_block_addr = block_addr; m_modified_size = modified_size; } - void set_info(new_addr_type block_addr, unsigned 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; @@ -121,8 +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, - mem_access_byte_mask_t byte_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; @@ -183,15 +183,14 @@ struct line_cache_block : public cache_block_t { m_set_readable_on_fill = false; m_set_byte_mask_on_fill = false; } - virtual void fill(unsigned time, mem_access_sector_mask_t sector_mask, - mem_access_byte_mask_t byte_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 ); m_status = m_set_modified_on_fill ? MODIFIED : VALID; - - if (m_set_readable_on_fill) - m_readable = true; + + 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; @@ -358,10 +357,10 @@ struct sector_cache_block : public cache_block_t { // 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; + m_readable[sidx] = true; + m_set_readable_on_fill[sidx] = false; } if (m_set_byte_mask_on_fill) set_byte_mask(byte_mask); @@ -416,8 +415,7 @@ struct sector_cache_block : public cache_block_t { 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); + if (m_status[i] == MODIFIED) sector_mask.set(i); } return sector_mask; } @@ -575,7 +573,7 @@ class cache_config { } exit_parse_error(); } - + switch (ct) { case 'N': m_cache_type = NORMAL; @@ -631,18 +629,19 @@ class cache_config { if (m_alloc_policy == STREAMING) { /* For streaming cache: - (1) we set the alloc policy to be on-fill to remove all line_alloc_fail stalls. - if the whole memory is allocated to the L1 cache, then make the allocation to be on_MISS - otherwise, make it ON_FILL to eliminate line allocation fails. - i.e. MSHR throughput is the same, independent on the L1 cache size/associativity - So, we set the allocation policy per kernel basis, see shader.cc, max_cta() function - + (1) we set the alloc policy to be on-fill to remove all line_alloc_fail + stalls. if the whole memory is allocated to the L1 cache, then make the + allocation to be on_MISS otherwise, make it ON_FILL to eliminate line + allocation fails. i.e. MSHR throughput is the same, independent on the L1 + cache size/associativity So, we set the allocation policy per kernel + basis, see shader.cc, max_cta() function + (2) We also set the MSHRs to be equal to max allocated cache lines. This is possible by moving TAG to be shared between cache line and MSHR enrty (i.e. for each cache line, there is an MSHR rntey associated with it). This is the easiest think we can think of to model (mimic) L1 streaming cache in Pascal and Volta - + 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/ @@ -697,8 +696,8 @@ class cache_config { } // detect invalid configuration - if ((m_alloc_policy == ON_FILL || m_alloc_policy == STREAMING) - and m_write_policy == WRITE_BACK) { + if ((m_alloc_policy == ON_FILL || m_alloc_policy == STREAMING) and + m_write_policy == WRITE_BACK) { // A writeback cache with allocate-on-fill policy will inevitably lead to // deadlock: The deadlock happens when an incoming cache-fill evicts a // dirty line, generating a writeback request. If the memory subsystem is @@ -746,7 +745,7 @@ class cache_config { break; case 'X': m_set_index_function = BITWISE_XORING_FUNCTION; - break; + break; default: exit_parse_error(); } @@ -779,7 +778,9 @@ class cache_config { virtual unsigned set_index(new_addr_type addr) const; - virtual unsigned get_max_cache_multiplier() const { return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER;} + virtual unsigned get_max_cache_multiplier() const { + return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; + } unsigned hash_function(new_addr_type addr, unsigned m_nset, unsigned m_line_sz_log2, unsigned m_nset_log2, @@ -826,9 +827,7 @@ 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; - } + write_policy_t get_write_policy() { return m_write_policy; } protected: void exit_parse_error() { @@ -903,17 +902,17 @@ class l1d_cache_config : public cache_config { unsigned l1_banks_byte_interleaving_log2; unsigned l1_banks_hashing_function; unsigned m_unified_cache_size; - virtual unsigned get_max_cache_multiplier() const { - // set * assoc * cacheline size. Then convert Byte to KB - // gpgpu_unified_cache_size is in KB while original_sz is in B - if (m_unified_cache_size > 0) { - unsigned original_size = m_nset * original_m_assoc * m_line_sz / 1024; - assert(m_unified_cache_size % original_size == 0); - return m_unified_cache_size / original_size; - } else { - return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; - } + virtual unsigned get_max_cache_multiplier() const { + // set * assoc * cacheline size. Then convert Byte to KB + // gpgpu_unified_cache_size is in KB while original_sz is in B + if (m_unified_cache_size > 0) { + unsigned original_size = m_nset * original_m_assoc * m_line_sz / 1024; + assert(m_unified_cache_size % original_size == 0); + return m_unified_cache_size / original_size; + } else { + return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; } + } }; class l2_cache_config : public cache_config { @@ -936,8 +935,7 @@ class tag_array { 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, + 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, @@ -948,7 +946,7 @@ class tag_array { 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(); } @@ -967,9 +965,7 @@ 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++; - } + void inc_dirty() { m_dirty++; } protected: // This constructor is intended for use only from derived classes that wish to diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index df30047..56ede05 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -249,7 +249,8 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); - option_parser_register(opp,"-gpgpu_l1_cache_write_ratio",OPT_UINT32,&m_L1D_config.m_wr_percent,"L1D write ratio","0"); + option_parser_register(opp, "-gpgpu_l1_cache_write_ratio", OPT_UINT32, + &m_L1D_config.m_wr_percent, "L1D write ratio", "0"); option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, "The number of L1 cache banks", "1"); @@ -327,11 +328,12 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register( opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size, "Size of shared memory per shader core (default 16kB)", "16384"); + option_parser_register(opp, "-gpgpu_shmem_option", OPT_CSTR, + &gpgpu_shmem_option, + "Option list of shared memory sizes", "0"); option_parser_register( - opp, "-gpgpu_shmem_option", OPT_CSTR, &gpgpu_shmem_option, - "Option list of shared memory sizes", "0"); - option_parser_register( - opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &m_L1D_config.m_unified_cache_size, + opp, "-gpgpu_unified_l1d_size", OPT_UINT32, + &m_L1D_config.m_unified_cache_size, "Size of unified data cache(L1D + shared memory) in KB", "0"); option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_BOOL, &adaptive_cache_config, "adaptive_cache_config", "0"); diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 0db6bd4..57e8ea9 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -57,20 +57,18 @@ mem_fetch *partition_mf_allocator::alloc(new_addr_type addr, return mf; } -mem_fetch *partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, - const active_mask_t &active_mask, - const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask, - unsigned size, bool wr, - unsigned long long cycle, - unsigned wid, unsigned sid, - unsigned tpc, mem_fetch *original_mf) const { - mem_access_t access(type, addr, size, wr, active_mask, byte_mask, - sector_mask, m_memory_config->gpgpu_ctx); +mem_fetch *partition_mf_allocator::alloc( + new_addr_type addr, mem_access_type type, const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, + unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, + mem_fetch *original_mf) const { + mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask, + m_memory_config->gpgpu_ctx); mem_fetch *mf = - new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, - sid, tpc, m_memory_config, cycle,original_mf); - return mf; + new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, + wid, sid, tpc, m_memory_config, cycle, original_mf); + return mf; } memory_partition_unit::memory_partition_unit(unsigned partition_id, const memory_config *config, @@ -725,11 +723,12 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) { mask.set(k); } - mem_fetch *n_mf = m_mf_allocator->alloc(mf->get_addr() + SECTOR_SIZE * i, - mf->get_access_type(),mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask,std::bitset().set(i), - SECTOR_SIZE,mf->is_write(),m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - mf->get_wid(),mf->get_sid(), mf->get_tpc(),mf); + mem_fetch *n_mf = m_mf_allocator->alloc( + mf->get_addr() + SECTOR_SIZE * i, mf->get_access_type(), + mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask, + std::bitset().set(i), SECTOR_SIZE, mf->is_write(), + m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(), + mf->get_sid(), mf->get_tpc(), mf); result.push_back(n_mf); } @@ -746,11 +745,12 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) { mask.set(k); } - mem_fetch *n_mf = m_mf_allocator->alloc(mf->get_addr(), - mf->get_access_type(),mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask,std::bitset().set(i), - SECTOR_SIZE,mf->is_write(),m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - mf->get_wid(),mf->get_sid(), mf->get_tpc(),mf); + mem_fetch *n_mf = m_mf_allocator->alloc( + mf->get_addr(), mf->get_access_type(), mf->get_access_warp_mask(), + mf->get_access_byte_mask() & mask, + std::bitset().set(i), SECTOR_SIZE, mf->is_write(), + m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(), + mf->get_sid(), mf->get_tpc(), mf); result.push_back(n_mf); } @@ -761,11 +761,12 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) { mask.set(k); } - mem_fetch *n_mf = m_mf_allocator->alloc(mf->get_addr() + SECTOR_SIZE * i, - mf->get_access_type(),mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask,std::bitset().set(i), - SECTOR_SIZE,mf->is_write(),m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - mf->get_wid(),mf->get_sid(), mf->get_tpc(),mf); + mem_fetch *n_mf = m_mf_allocator->alloc( + mf->get_addr() + SECTOR_SIZE * i, mf->get_access_type(), + mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask, + std::bitset().set(i), SECTOR_SIZE, + mf->is_write(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, + mf->get_wid(), mf->get_sid(), mf->get_tpc(), mf); result.push_back(n_mf); } diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 59432b8..beed765 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -52,13 +52,12 @@ class partition_mf_allocator : public mem_fetch_allocator { unsigned size, bool wr, unsigned long long cycle) const; virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, - const active_mask_t &active_mask, - const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask, - unsigned size, bool wr, - unsigned long long cycle, - unsigned wid, unsigned sid, - unsigned tpc, mem_fetch *original_mf) const; + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, + unsigned size, bool wr, unsigned long long cycle, + unsigned wid, unsigned sid, unsigned tpc, + mem_fetch *original_mf) const; private: const memory_config *m_memory_config; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 51366de..c65affd 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -62,21 +62,19 @@ mem_fetch *shader_core_mem_fetch_allocator::alloc( return mf; } -mem_fetch *shader_core_mem_fetch_allocator::alloc(new_addr_type addr, mem_access_type type, - const active_mask_t &active_mask, - const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask, - unsigned size, bool wr, - unsigned long long cycle, - unsigned wid, unsigned sid, - unsigned tpc, mem_fetch *original_mf) const { - mem_access_t access(type, addr, size, wr, active_mask, byte_mask, - sector_mask, m_memory_config->gpgpu_ctx); - mem_fetch *mf = - new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, - m_core_id, m_cluster_id, m_memory_config, cycle,original_mf); - return mf; - } +mem_fetch *shader_core_mem_fetch_allocator::alloc( + new_addr_type addr, mem_access_type type, const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, + unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, + mem_fetch *original_mf) const { + mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask, + m_memory_config->gpgpu_ctx); + mem_fetch *mf = new mem_fetch( + access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, m_core_id, + m_cluster_id, m_memory_config, cycle, original_mf); + return mf; +} ///////////////////////////////////////////////////////////////////////////// std::list shader_core_ctx::get_regs_written(const inst_t &fvt) const { @@ -142,8 +140,8 @@ void shader_core_ctx::create_front_pipeline() { m_pipeline_reg[ID_OC_INT].get_size()); for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { if (m_config->m_specialized_unit[j].num_units > 0) - assert(m_config->gpgpu_num_sched_per_core == - m_config->m_specialized_unit[j].id_oc_spec_reg_width); + assert(m_config->gpgpu_num_sched_per_core == + m_config->m_specialized_unit[j].id_oc_spec_reg_width); } } @@ -187,15 +185,18 @@ void shader_core_ctx::create_schedulers() { // must currently occur after all inputs have been initialized. std::string sched_config = m_config->gpgpu_scheduler_string; const concrete_scheduler scheduler = - sched_config.find("lrr") != std::string::npos ? CONCRETE_SCHEDULER_LRR - : sched_config.find("two_level_active") != std::string::npos - ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE - : sched_config.find("gto") != std::string::npos ? CONCRETE_SCHEDULER_GTO - : sched_config.find("old") != std::string::npos - ? CONCRETE_SCHEDULER_OLDEST_FIRST - : sched_config.find("warp_limiting") != std::string::npos - ? CONCRETE_SCHEDULER_WARP_LIMITING - : NUM_CONCRETE_SCHEDULERS; + sched_config.find("lrr") != std::string::npos + ? CONCRETE_SCHEDULER_LRR + : sched_config.find("two_level_active") != std::string::npos + ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE + : sched_config.find("gto") != std::string::npos + ? CONCRETE_SCHEDULER_GTO + : sched_config.find("old") != std::string::npos + ? CONCRETE_SCHEDULER_OLDEST_FIRST + : sched_config.find("warp_limiting") != + std::string::npos + ? CONCRETE_SCHEDULER_WARP_LIMITING + : NUM_CONCRETE_SCHEDULERS; assert(scheduler != NUM_CONCRETE_SCHEDULERS); for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++) { @@ -1246,20 +1247,21 @@ void scheduler_unit::cycle() { previous_issued_inst_exec_type = exec_unit_type_t::MEM; } } else { - // This code need to be refactored if (pI->op != TENSOR_CORE_OP && pI->op != SFU_OP && pI->op != DP_OP && !(pI->op >= SPEC_UNIT_START_ID)) { bool execute_on_SP = false; bool execute_on_INT = false; - bool sp_pipe_avail = - (m_shader->m_config->gpgpu_num_sp_units > 0) && - m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool int_pipe_avail = - (m_shader->m_config->gpgpu_num_int_units > 0) && - m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); - + bool sp_pipe_avail = + (m_shader->m_config->gpgpu_num_sp_units > 0) && + m_sp_out->has_free(m_shader->m_config->sub_core_model, + m_id); + bool int_pipe_avail = + (m_shader->m_config->gpgpu_num_int_units > 0) && + m_int_out->has_free(m_shader->m_config->sub_core_model, + m_id); + // if INT unit pipline exist, then execute ALU and INT // operations on INT unit and SP-FPU on SP unit (like in Volta) // if INT unit pipline does not exist, then execute all ALU, INT @@ -1320,10 +1322,10 @@ void scheduler_unit::cycle() { (pI->op == DP_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::DP)) { - bool dp_pipe_avail = - (m_shader->m_config->gpgpu_num_dp_units > 0) && - m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); + (m_shader->m_config->gpgpu_num_dp_units > 0) && + m_dp_out->has_free(m_shader->m_config->sub_core_model, + m_id); if (dp_pipe_avail) { m_shader->issue_warp(*m_dp_out, pI, active_mask, warp_id, @@ -1340,10 +1342,10 @@ void scheduler_unit::cycle() { (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP)) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::SFU)) { - bool sfu_pipe_avail = - (m_shader->m_config->gpgpu_num_sfu_units > 0) && - m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); + (m_shader->m_config->gpgpu_num_sfu_units > 0) && + m_sfu_out->has_free(m_shader->m_config->sub_core_model, + m_id); if (sfu_pipe_avail) { m_shader->issue_warp(*m_sfu_out, pI, active_mask, warp_id, @@ -1356,11 +1358,10 @@ void scheduler_unit::cycle() { } else if ((pI->op == TENSOR_CORE_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::TENSOR)) { - bool tensor_core_pipe_avail = - (m_shader->m_config->gpgpu_num_tensor_core_units > 0) && - m_tensor_core_out->has_free( - m_shader->m_config->sub_core_model, m_id); + (m_shader->m_config->gpgpu_num_tensor_core_units > 0) && + m_tensor_core_out->has_free( + m_shader->m_config->sub_core_model, m_id); if (tensor_core_pipe_avail) { m_shader->issue_warp(*m_tensor_core_out, pI, active_mask, @@ -2007,8 +2008,10 @@ void ldst_unit::L1_latency_queue_cycle() { l1_latency_queue[j][0] = NULL; if (m_config->m_L1D_config.get_write_policy() != WRITE_THROUGH && mf_next->get_inst().is_store() && - (m_config->m_L1D_config.get_write_allocate_policy() == FETCH_ON_WRITE || - m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && + (m_config->m_L1D_config.get_write_allocate_policy() == + FETCH_ON_WRITE || + m_config->m_L1D_config.get_write_allocate_policy() == + LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { unsigned dec_ack = (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC) @@ -2316,7 +2319,7 @@ void dp_unit ::issue(register_set &source_reg) { } void specialized_unit ::issue(register_set &source_reg) { - warp_inst_t **ready_reg = + warp_inst_t **ready_reg = source_reg.get_ready(m_config->sub_core_model, m_issue_reg_id); // m_core->incexecstat((*ready_reg)); (*ready_reg)->op_pipe = SPECIALIZED__OP; @@ -3349,15 +3352,15 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { unsigned max_assoc = m_L1D_config.get_max_assoc(); for (std::vector::const_iterator it = shmem_opt_list.begin(); - it < shmem_opt_list.end(); it++) { + it < shmem_opt_list.end(); it++) { if (total_shmem <= *it) { - float l1_ratio = 1 - ((float) *(it) / total_unified); + float l1_ratio = 1 - ((float)*(it) / total_unified); m_L1D_config.set_assoc(max_assoc * l1_ratio); l1d_configured = true; break; } } - + assert(l1d_configured && "no shared memory option found"); break; } @@ -3365,16 +3368,16 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { assert(0); } - if(m_L1D_config.is_streaming()) { - //for streaming cache, if the whole memory is allocated - //to the L1 cache, then make the allocation to be on_MISS - //otherwise, make it ON_FILL to eliminate line allocation fails - //i.e. MSHR throughput is the same, independent on the L1 cache size/associativity - if(total_shmem == 0) { + if (m_L1D_config.is_streaming()) { + // for streaming cache, if the whole memory is allocated + // to the L1 cache, then make the allocation to be on_MISS + // otherwise, make it ON_FILL to eliminate line allocation fails + // i.e. MSHR throughput is the same, independent on the L1 cache + // size/associativity + if (total_shmem == 0) { m_L1D_config.set_allocation_policy(ON_MISS); printf("GPGPU-Sim: Reconfigure L1 allocation to ON_MISS\n"); - } - else { + } else { m_L1D_config.set_allocation_policy(ON_FILL); printf("GPGPU-Sim: Reconfigure L1 allocation to ON_FILL\n"); } diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 8662313..2d2f051 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1496,8 +1496,8 @@ class shader_core_config : public core_config { break; // we only accept continuous specialized_units, i.e., 1,2,3,4 } - //parse gpgpu_shmem_option for adpative cache config - if(adaptive_cache_config) { + // parse gpgpu_shmem_option for adpative cache config + if (adaptive_cache_config) { for (unsigned i = 0; i < strlen(gpgpu_shmem_option); i++) { char option[4]; int j = 0; @@ -1520,7 +1520,6 @@ class shader_core_config : public core_config { } std::sort(shmem_opt_list.begin(), shmem_opt_list.end()); } - } void reg_options(class OptionParser *opp); unsigned max_cta(const kernel_info_t &k) const; @@ -1899,13 +1898,11 @@ class shader_core_mem_fetch_allocator : public mem_fetch_allocator { mem_fetch *alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const; mem_fetch *alloc(new_addr_type addr, mem_access_type type, - const active_mask_t &active_mask, - const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask, - unsigned size, bool wr, - unsigned long long cycle, - unsigned wid, unsigned sid, - unsigned tpc, mem_fetch *original_mf) const; + const active_mask_t &active_mask, + const mem_access_byte_mask_t &byte_mask, + const mem_access_sector_mask_t §or_mask, unsigned size, + bool wr, unsigned long long cycle, unsigned wid, + unsigned sid, unsigned tpc, mem_fetch *original_mf) const; mem_fetch *alloc(const warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const { warp_inst_t inst_copy = inst; -- cgit v1.3 From 04462cbf5b56e0416c3a733b4214351ac227f4c0 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Thu, 3 Jun 2021 13:55:44 -0400 Subject: update readable --- src/gpgpu-sim/gpu-cache.cc | 30 +++++++++++++++++++++++++++--- src/gpgpu-sim/gpu-cache.h | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.h') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 28d3215..a35f502 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -284,10 +284,12 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, // 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) { - // if number of dirty lines in the cache is greater than - // a specific value all_reserved = false; if (line->is_invalid_line()) { invalid_line = index; @@ -354,7 +356,7 @@ 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); + // 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_dirty_byte_mask(), @@ -1191,6 +1193,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 @@ -1207,6 +1228,7 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr, } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); + update_m_readable(mf,cache_index); return HIT; } @@ -1230,6 +1252,7 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr, } 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); @@ -1543,6 +1566,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( 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 diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 7a2a8d9..67d084c 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -1570,7 +1570,7 @@ class data_cache : public baseline_cache { /// Sends write request to lower level memory (write or writeback) void send_write_request(mem_fetch *mf, cache_event request, unsigned time, std::list &events); - + void update_m_readable(mem_fetch *mf, unsigned cache_index); // Member Function pointers - Set by configuration options // to the functions below each grouping /******* Write-hit configs *******/ -- cgit v1.3