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.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 75c3691..d44c959 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1455,16 +1455,19 @@ 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()); 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()); } if (mf->get_access_byte_mask().count() == m_config.get_atom_sz()) { block->set_m_readable(true, mf->get_access_sector_mask()); } else { block->set_m_readable(false, mf->get_access_sector_mask()); + if (m_status == HIT_RESERVED) + block->set_readable_on_fill(true, mf->get_access_sector_mask()); } if (m_status != RESERVATION_FAIL) { -- 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.cc') 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 f3a00778b98cf101c8052e9fe1dd2d4c08185b7e Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Fri, 12 Feb 2021 16:13:46 -0500 Subject: bug fix was_writeback_sent --- src/gpgpu-sim/gpu-cache.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index af22c4c..eb95004 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -496,8 +496,10 @@ bool was_writeback_sent(const std::list &events, cache_event &wb_event) { for (std::list::const_iterator e = events.begin(); e != events.end(); e++) { - if ((*e).m_cache_event_type == WRITE_BACK_REQUEST_SENT) wb_event = *e; - return true; + if ((*e).m_cache_event_type == WRITE_BACK_REQUEST_SENT) { + wb_event = *e; + return true; + } } return false; } -- 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.cc') 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.cc') 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 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.cc') 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 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.cc') 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 e05fa4a676c2b082f1ebb34d051f43ad05d4a82c Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:33:30 -0500 Subject: little bug fix - flush() --- src/gpgpu-sim/gpu-cache.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index ded8004..8d44f15 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -426,9 +426,10 @@ void tag_array::flush() { for (unsigned i = 0; i < m_config.get_num_lines(); i++) if (m_lines[i]->is_modified_line()) { - for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) + for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) { m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); m_dirty--; + } } is_used = false; -- 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.cc') 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.cc') 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 64bf6fd7a44a32773389e900862bd9c0527a87e9 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Thu, 18 Mar 2021 13:31:41 -0400 Subject: dirty counter not resetting after kernel finish --- src/gpgpu-sim/gpu-cache.cc | 80 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 46813e7..5ac202c 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -210,6 +210,7 @@ void tag_array::init(int core_id, int type_id) { m_core_id = core_id; m_type_id = type_id; is_used = false; + m_dirty = 0; } void tag_array::add_pending_line(mem_fetch *mf) { @@ -250,7 +251,22 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, unsigned long long valid_timestamp = (unsigned)-1; bool all_reserved = true; + unsigned count = 0; + if (m_config.m_wr_percent == (unsigned)25) { + for (unsigned i = 0; i < m_config.m_nset * m_config.m_assoc; i++) { + if (m_lines[i]->is_modified_line()) { + m_lines[i]->is_modified_line(); + count++; + } + } + if (count != m_dirty) { + printf("count = %u, m_dirty = %u",count,m_dirty); + fflush(stdout); + assert(0 && "m_dirty miss match"); + printf("count = %u, m_dirty = %u",count,m_dirty); + } + } // check for hit or pending hit for (unsigned way = 0; way < m_config.m_assoc; way++) { unsigned index = set_index * m_config.m_assoc + way; @@ -279,15 +295,17 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, } } if (!line->is_reserved_line()) { - all_reserved = false; - if (line->is_invalid_line()) { - invalid_line = index; - } else { - // valid line : keep track of most appropriate replacement candidate - if (!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 (!line->is_modified_line() || + 100 * m_dirty / (m_config.m_nset * m_config.m_assoc) >= + m_config.m_wr_percent) { + all_reserved = false; + if (line->is_invalid_line()) { + invalid_line = index; + } else { + // valid line : keep track of most appropriate replacement candidate + + // 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,6 +381,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, m_lines[idx]->get_modified_size(), m_lines[idx]->get_byte_mask(), m_lines[idx]->get_sector_mask()); + m_dirty--; } m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time, mf->get_access_sector_mask()); @@ -373,8 +392,12 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, m_sector_miss++; shader_cache_access_log(m_core_id, m_type_id, 1); // log cache misses if (m_config.m_alloc_policy == ON_MISS) { + bool before = m_lines[idx]->is_modified_line(); ((sector_cache_block *)m_lines[idx]) ->allocate_sector(time, mf->get_access_sector_mask()); + if (before && !m_lines[idx]->is_modified_line()) { + m_dirty--; + } } break; case RESERVATION_FAIL: @@ -400,22 +423,35 @@ void tag_array::fill(new_addr_type addr, unsigned time, // assert( m_config.m_alloc_policy == ON_FILL ); unsigned idx; enum cache_request_status status = probe(addr, idx, mask); + bool before = false; // assert(status==MISS||status==SECTOR_MISS); // MSHR should have prevented // redundant memory request - if (status == MISS) + if (status == MISS) { + before = m_lines[idx]->is_modified_line(); m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time, mask); - else if (status == SECTOR_MISS) { + } else if (status == SECTOR_MISS) { assert(m_config.m_cache_type == SECTOR); + before = m_lines[idx]->is_modified_line(); ((sector_cache_block *)m_lines[idx])->allocate_sector(time, mask); } - + if (before && !m_lines[idx]->is_modified_line()) { + m_dirty--; + } + before = m_lines[idx]->is_modified_line(); m_lines[idx]->fill(time, mask, byte_mask); + if (m_lines[idx]->is_modified_line() && !before) { + m_dirty++; + } } void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) { assert(m_config.m_alloc_policy == ON_MISS); + bool before = m_lines[index]->is_modified_line(); m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask()); + if (m_lines[index]->is_modified_line() && !before) { + m_dirty++; + } } // TODO: we need write back the flushed data to the upper level @@ -424,9 +460,9 @@ void tag_array::flush() { for (unsigned i = 0; i < m_config.get_num_lines(); i++) if (m_lines[i]->is_modified_line()) { + m_dirty--; for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) { m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); - m_dirty--; } } @@ -1078,6 +1114,9 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) { if (has_atomic) { assert(m_config.m_alloc_policy == ON_MISS); cache_block_t *block = m_tag_array->get_block(e->second.m_cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); // mark line as dirty for // atomic operation @@ -1187,6 +1226,9 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr, new_addr_type block_addr = m_config.block_addr(addr); m_tag_array->access(block_addr, time, cache_index, mf); // update LRU state cache_block_t *block = m_tag_array->get_block(cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); @@ -1207,6 +1249,9 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr, new_addr_type block_addr = m_config.block_addr(addr); m_tag_array->access(block_addr, time, cache_index, mf); // update LRU state cache_block_t *block = m_tag_array->get_block(cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); @@ -1358,6 +1403,9 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf); assert(status != HIT); cache_block_t *block = m_tag_array->get_block(cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); if (status == HIT_RESERVED) @@ -1479,6 +1527,9 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf); assert(m_status != HIT); cache_block_t *block = m_tag_array->get_block(cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); if (m_status == HIT_RESERVED) { @@ -1546,6 +1597,9 @@ enum cache_request_status data_cache::rd_hit_base( if (mf->isatomic()) { assert(mf->get_access_type() == GLOBAL_ACC_R); cache_block_t *block = m_tag_array->get_block(cache_index); + if (!block->is_modified_line()) { + m_tag_array->inc_dirty(); + } block->set_status(MODIFIED, mf->get_access_sector_mask()); // mark line as block->set_byte_mask(mf); -- cgit v1.3 From a374b330ac3bec0b47ce588adf72af89e5cd9307 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Fri, 26 Mar 2021 16:33:41 -0400 Subject: remove MSHR_HIT from cache total access --- src/gpgpu-sim/gpu-cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 5ac202c..d2f9fef 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -819,7 +819,7 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const { cache_request_status_str((enum cache_request_status)status), m_stats[type][status]); - if (status != RESERVATION_FAIL) + if (status != RESERVATION_FAIL && status != MSHR_HIT) total_access[type] += m_stats[type][status]; } } -- 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.cc') 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 994fb19e160e3897b5662fb7e6946a3802fde794 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 4 May 2021 15:17:57 -0400 Subject: reset dirty counter --- src/gpgpu-sim/gpu-cache.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 9c65476..e88a646 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -428,12 +428,10 @@ void tag_array::fill(new_addr_type addr, unsigned time, // assert(status==MISS||status==SECTOR_MISS); // MSHR should have prevented // redundant memory request if (status == MISS) { - before = m_lines[idx]->is_modified_line(); m_lines[idx]->allocate(m_config.tag(addr), m_config.block_addr(addr), time, mask); } else if (status == SECTOR_MISS) { assert(m_config.m_cache_type == SECTOR); - before = m_lines[idx]->is_modified_line(); ((sector_cache_block *)m_lines[idx])->allocate_sector(time, mask); } if (before && !m_lines[idx]->is_modified_line()) { @@ -458,10 +456,10 @@ void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) { // 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()) { - m_dirty--; for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) { m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); } @@ -472,6 +470,7 @@ void tag_array::flush() { 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++) -- cgit v1.3 From 73069303b3dc0845e33b9ddafa7e6697fe3deb38 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 11 May 2021 22:45:44 -0400 Subject: remove runtime check of dirty counter --- src/gpgpu-sim/gpu-cache.cc | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index e88a646..9e1db8b 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -251,22 +251,6 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, unsigned long long valid_timestamp = (unsigned)-1; bool all_reserved = true; - unsigned count = 0; - if (m_config.m_wr_percent == (unsigned)25) { - for (unsigned i = 0; i < m_config.m_nset * m_config.m_assoc; i++) { - if (m_lines[i]->is_modified_line()) { - m_lines[i]->is_modified_line(); - count++; - } - } - if (count != m_dirty) { - printf("count = %u, m_dirty = %u",count,m_dirty); - fflush(stdout); - assert(0 && "m_dirty miss match"); - printf("count = %u, m_dirty = %u",count,m_dirty); - - } - } // check for hit or pending hit for (unsigned way = 0; way < m_config.m_assoc; way++) { unsigned index = set_index * m_config.m_assoc + way; -- 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.cc') 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 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.cc') 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.cc') 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 f665ad5a49620b47118cbf6d578b469155e2a500 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Thu, 20 May 2021 20:52:06 -0400 Subject: L2 breakdown - reuse mf allocator --- src/abstract_hardware_model.h | 4 +++- src/gpgpu-sim/gpu-cache.cc | 10 ++++---- src/gpgpu-sim/l2cache.cc | 56 ++++++++++++++++--------------------------- src/gpgpu-sim/l2cache.h | 4 +++- src/gpgpu-sim/shader.cc | 19 ++++++++------- src/gpgpu-sim/shader.h | 4 +++- 6 files changed, 45 insertions(+), 52 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index b33c50b..60d7328 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -876,7 +876,9 @@ class mem_fetch_allocator { 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; + 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/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 297a94c..23c5592 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1338,7 +1338,7 @@ enum cache_request_status data_cache::wr_miss_wa_naive( 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); + 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); @@ -1391,7 +1391,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( 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); + 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); @@ -1464,7 +1464,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( 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); + 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); @@ -1549,7 +1549,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( 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); + 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); @@ -1631,7 +1631,7 @@ enum cache_request_status data_cache::rd_miss_base( 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); + 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/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 00b14d7..0db6bd4 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -57,18 +57,19 @@ 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, +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 { + 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, -1, - -1, -1, m_memory_config, cycle); + 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, @@ -724,16 +725,11 @@ 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); } - const mem_access_t *ma = new mem_access_t( - mf->get_access_type(), mf->get_addr() + SECTOR_SIZE * i, SECTOR_SIZE, - mf->is_write(), mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask, - std::bitset().set(i), m_gpu->gpgpu_ctx); - - mem_fetch *n_mf = - new mem_fetch(*ma, NULL, mf->get_ctrl_size(), mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), - m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, 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); } @@ -750,16 +746,11 @@ 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); } - const mem_access_t *ma = new mem_access_t( - mf->get_access_type(), mf->get_addr(), SECTOR_SIZE, - mf->is_write(), mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask, - std::bitset().set(i), m_gpu->gpgpu_ctx); - - mem_fetch *n_mf = - new mem_fetch(*ma, NULL, mf->get_ctrl_size(), mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), - m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, 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); } @@ -770,16 +761,11 @@ 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); } - const mem_access_t *ma = new mem_access_t( - mf->get_access_type(), mf->get_addr() + SECTOR_SIZE * i, - SECTOR_SIZE, mf->is_write(), mf->get_access_warp_mask(), - mf->get_access_byte_mask() & mask, - std::bitset().set(i), m_gpu->gpgpu_ctx); - - mem_fetch *n_mf = - new mem_fetch(*ma, NULL, mf->get_ctrl_size(), mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), - m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, 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 1f5d7c4..59432b8 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -56,7 +56,9 @@ class partition_mf_allocator : public mem_fetch_allocator { 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; + 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 7f27b7b..51366de 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -62,18 +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) const { +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, -1, - m_core_id, m_cluster_id, m_memory_config, cycle); + 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; } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 42bbdcb..8662313 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1903,7 +1903,9 @@ class shader_core_mem_fetch_allocator : public mem_fetch_allocator { 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; + 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 b814c52fe9c4538669d845c5f05b247348f6fd1d Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Fri, 21 May 2021 15:12:43 -0400 Subject: cast to float - dirty line percentage --- src/gpgpu-sim/gpu-cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 23c5592..7e7d2ad 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -282,7 +282,7 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, // 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) 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 -- 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.cc') 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.cc') 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 From 0f088dc11a47cb3de905de3483f6a1c019b7d283 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 16 Jun 2021 10:22:57 -0400 Subject: correct dirty counter --- src/gpgpu-sim/gpu-cache.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index a35f502..c93ac5f 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -428,9 +428,11 @@ 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_dirty++; + bool before = m_lines[index]->is_modified_line(); + m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask()); + if (m_lines[index]->is_modified_line() && !before) { + m_dirty++; + } } // TODO: we need write back the flushed data to the upper level -- cgit v1.3 From 3cf24b8afea9a519fa052e68cf10c1f774ab5f68 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 22 Jun 2021 20:27:43 -0400 Subject: WT in lazy fetch on read --- src/gpgpu-sim/gpu-cache.cc | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'src/gpgpu-sim/gpu-cache.cc') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index c93ac5f..7416246 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1511,35 +1511,17 @@ 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 - // 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; - } + 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 + } + if (m_config.m_write_policy == WRITE_THROUGH) { send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); } -- cgit v1.3