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') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 1c36d22..763705f 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -284,15 +284,20 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, invalid_line = index; } else { // valid line : keep track of most appropriate replacement candidate - if (m_config.m_replacement_policy == LRU) { - if (line->get_last_access_time() < valid_timestamp) { - valid_timestamp = line->get_last_access_time(); - valid_line = index; - } - } else if (m_config.m_replacement_policy == FIFO) { - if (line->get_alloc_time() < valid_timestamp) { - valid_timestamp = line->get_alloc_time(); - valid_line = index; + if (!line->get_status(mask) == MODIFIED || + 100 * m_dirty/(m_config.m_nset * m_config.m_assoc) >= m_config.m_wr_percent) { + // don't evict write until dirty lines reach threshold + // make sure at least 1 candidate is assigned + if (m_config.m_replacement_policy == LRU) { + if (line->get_last_access_time() < valid_timestamp) { + valid_timestamp = line->get_last_access_time(); + valid_line = index; + } + } else if (m_config.m_replacement_policy == FIFO) { + if (line->get_alloc_time() < valid_timestamp) { + valid_timestamp = line->get_alloc_time(); + valid_line = index; + } } } } @@ -418,6 +423,7 @@ void tag_array::flush() { if (m_lines[i]->is_modified_line()) { for (unsigned j = 0; j < SECTOR_CHUNCK_SIZE; j++) m_lines[i]->set_status(INVALID, mem_access_sector_mask_t().set(j)); + m_dirty--; } is_used = false; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 00c09ae..9dbfe82 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -498,10 +498,10 @@ class cache_config { char ct, rp, wp, ap, mshr_type, wap, sif; int ntok = - sscanf(config, "%c:%u:%u:%u,%c:%c:%c:%c:%c,%c:%u:%u,%u:%u,%u", &ct, + sscanf(config, "%c:%u:%u:%u,%c:%c:%c:%c:%c,%c:%u:%u,%u:%u,%u,%u", &ct, &m_nset, &m_line_sz, &m_assoc, &rp, &wp, &ap, &wap, &sif, &mshr_type, &m_mshr_entries, &m_mshr_max_merge, - &m_miss_queue_size, &m_result_fifo_entries, &m_data_port_width); + &m_miss_queue_size, &m_result_fifo_entries, &m_data_port_width, &m_wr_percent); if (ntok < 12) { if (!strcmp(config, "none")) { @@ -801,6 +801,7 @@ class cache_config { unsigned m_data_port_width; //< number of byte the cache can access per cycle enum set_index_function m_set_index_function; // Hash, linear, or custom set index function + unsigned m_wr_percent; friend class tag_array; friend class baseline_cache; @@ -897,6 +898,7 @@ class tag_array { // allocated but not filled unsigned m_res_fail; unsigned m_sector_miss; + unsigned m_dirty; // performance counters for calculating the amount of misses within a time // window -- cgit v1.3 From 615f173c25883fbc8db0363279e2eb216acb8c7e Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Sat, 20 Feb 2021 16:03:42 -0500 Subject: store ack for new waps --- src/gpgpu-sim/gpu-cache.h | 6 ++++++ src/gpgpu-sim/shader.cc | 12 ++++++++++++ 2 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 9dbfe82..381ce94 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -754,6 +754,9 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; + write_allocate_policy_t get_write_allocate_policy() { + return m_write_alloc_policy; + } protected: void exit_parse_error() { @@ -878,6 +881,9 @@ class tag_array { void update_cache_parameters(cache_config &config); void add_pending_line(mem_fetch *mf); void remove_pending_line(mem_fetch *mf); + void inc_dirty() { + m_dirty++; + } protected: // This constructor is intended for use only from derived classes that wish to diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 14d9044..4769ca8 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1974,6 +1974,18 @@ void ldst_unit::L1_latency_queue_cycle() { } else { assert(status == MISS || status == HIT_RESERVED); l1_latency_queue[j][0] = NULL; + if (mf_next->get_inst().is_store() && + (m_config->m_L1D_config.get_write_allocate_policy() == FETCH_ON_WRITE || + m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && + !was_writeallocate_sent(events)) { + unsigned dec_ack = + (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC) + ? (mf_next->get_data_size() / SECTOR_SIZE) + : 1; + mf_next->set_reply(); + for (unsigned i = 0; i < dec_ack; ++i) m_core->store_ack(mf_next); + if (!write_sent && !read_sent) delete mf_next; + } } } -- cgit v1.3 From ad7204189b79be89575d969b305c529a31a2a765 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:30:27 -0500 Subject: sending cache block byte mask --- src/abstract_hardware_model.h | 6 ++++++ src/gpgpu-sim/gpu-cache.cc | 21 ++++++++++++++++----- src/gpgpu-sim/gpu-cache.h | 28 ++++++++++++++++++++++++++++ src/gpgpu-sim/l2cache.cc | 14 ++++++++++++++ src/gpgpu-sim/l2cache.h | 6 ++++++ src/gpgpu-sim/shader.cc | 15 +++++++++++++++ src/gpgpu-sim/shader.h | 6 ++++++ 7 files changed, 91 insertions(+), 5 deletions(-) (limited to 'src') 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 bb19c0cbfa2dc8082496a279f37f48695b7c4185 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:32:29 -0500 Subject: update mf breakdown at L2 --- src/gpgpu-sim/l2cache.cc | 92 +++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index cd04af5..63119ee 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -555,10 +555,15 @@ void memory_sub_partition::cache_cycle(unsigned cycle) { m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { - mf->set_reply(); - mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE, - m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); - m_L2_icnt_queue->push(mf); + if (mf->get_access_type() == L1_WRBK_ACC) { + m_request_tracker.erase(mf); + delete mf; + } else { + mf->set_reply(); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); + m_L2_icnt_queue->push(mf); + } } // L2 cache accepted request m_icnt_L2_queue->pop(); @@ -708,71 +713,32 @@ bool memory_sub_partition::busy() const { return !m_request_tracker.empty(); } std::vector memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { std::vector result; - + mem_access_sector_mask_t sector_mask = mf->get_access_sector_mask(); if (mf->get_data_size() == SECTOR_SIZE && mf->get_access_sector_mask().count() == 1) { result.push_back(mf); - } else if (mf->get_data_size() == 128 || mf->get_data_size() == 64) { - // We only accept 32, 64 and 128 bytes reqs - unsigned start = 0, end = 0; - if (mf->get_data_size() == 128) { - start = 0; - end = 3; - } else if (mf->get_data_size() == 64 && - mf->get_access_sector_mask().to_string() == "1100") { - start = 2; - end = 3; - } else if (mf->get_data_size() == 64 && - mf->get_access_sector_mask().to_string() == "0011") { - start = 0; - end = 1; - } else if (mf->get_data_size() == 64 && - (mf->get_access_sector_mask().to_string() == "1111" || - mf->get_access_sector_mask().to_string() == "0000")) { - if (mf->get_addr() % 128 == 0) { - start = 0; - end = 1; - } else { - start = 2; - end = 3; + } else { + for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; i++) { + if (sector_mask.test(i)) { + mem_access_byte_mask_t mask; + 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); + + result.push_back(n_mf); } - } else { - printf( - "Invalid sector received, address = 0x%06llx, sector mask = %s, data " - "size = %d", - mf->get_addr(), mf->get_access_sector_mask(), mf->get_data_size()); - assert(0 && "Undefined sector mask is received"); } - - std::bitset byte_sector_mask; - byte_sector_mask.reset(); - for (unsigned k = start * SECTOR_SIZE; k < SECTOR_SIZE; ++k) - byte_sector_mask.set(k); - - for (unsigned j = start, i = 0; j <= end; ++j, ++i) { - 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() & byte_sector_mask, - std::bitset().set(j), 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); - - result.push_back(n_mf); - byte_sector_mask <<= SECTOR_SIZE; - } - } else { - printf( - "Invalid sector received, address = 0x%06llx, sector mask = %d, byte " - "mask = , data size = %u", - mf->get_addr(), mf->get_access_sector_mask().count(), - mf->get_data_size()); - assert(0 && "Undefined data size is received"); } - return result; } -- 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') 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') 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') 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 40077df94f1afcfaabdc9599d7a2c25d3d98da8a Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 8 Mar 2021 17:58:02 -0500 Subject: solve deadlock for non-sectored cache configs --- src/gpgpu-sim/l2cache.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src') diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 63119ee..00b14d7 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -717,6 +717,52 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { if (mf->get_data_size() == SECTOR_SIZE && mf->get_access_sector_mask().count() == 1) { result.push_back(mf); + } else if (mf->get_data_size() == 128) { + // break down every sector + mem_access_byte_mask_t mask; + for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; i++) { + 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); + + result.push_back(n_mf); + } + } else if (mf->get_data_size() == 64 && + (mf->get_access_sector_mask().to_string() == "1111" || + mf->get_access_sector_mask().to_string() == "0000")) { + unsigned start; + if (mf->get_addr() % 128 == 0) + start = 0; + else + start = 2; + mem_access_byte_mask_t mask; + for (unsigned i = start; i < start + 2; i++) { + 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); + + result.push_back(n_mf); + } } else { for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; i++) { if (sector_mask.test(i)) { @@ -739,6 +785,7 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { } } } + if (result.size() == 0) assert(0 && "no mf sent"); return result; } -- 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') 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') 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') 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') 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') 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') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 9e1db8b..390bacc 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1494,16 +1494,39 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr, unsigned cache_index, mem_fetch *mf, unsigned time, std::list &events, enum cache_request_status status) { new_addr_type block_addr = m_config.block_addr(addr); + new_addr_type mshr_addr = m_config.mshr_addr(mf->get_addr()); // if the request writes to the whole cache line/sector, then, write and set // cache line Modified. and no need to send read request to memory or reserve // mshr - if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); - return RESERVATION_FAIL; // cannot handle request this cycle + // Write allocate, maximum 2 requests (write miss, write back request) + // Conservatively ensure the worst-case request can be handled this + // cycle + if (m_config.m_write_policy == WRITE_THROUGH) { + bool mshr_hit = m_mshrs.probe(mshr_addr); + bool mshr_avail = !m_mshrs.full(mshr_addr); + if (miss_queue_full(1) || + (!(mshr_hit && mshr_avail) && + !(!mshr_hit && mshr_avail && + (m_miss_queue.size() < m_config.m_miss_queue_size)))) { + // check what is the exactly the failure reason + if (miss_queue_full(1)) + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + else if (mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + else if (!mshr_hit && !mshr_avail) + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + else + assert(0); + + return RESERVATION_FAIL; + } + + send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); } + bool wb = false; evicted_block_info evicted; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index c2e302e..6811b86 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -821,6 +821,9 @@ class cache_config { write_allocate_policy_t get_write_allocate_policy() { return m_write_alloc_policy; } + write_policy_t get_write_policy() { + return m_write_policy; + } protected: void exit_parse_error() { diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 4b4c98d..22bd8e9 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1989,9 +1989,10 @@ void ldst_unit::L1_latency_queue_cycle() { } else { assert(status == MISS || status == HIT_RESERVED); l1_latency_queue[j][0] = NULL; - if (mf_next->get_inst().is_store() && + if (m_config->m_L1D_config.get_write_policy() != WRITE_THROUGH && + mf_next->get_inst().is_store() && (m_config->m_L1D_config.get_write_allocate_policy() == FETCH_ON_WRITE || - m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && + m_config->m_L1D_config.get_write_allocate_policy() == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { unsigned dec_ack = (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC) -- cgit v1.3 From f7833519471ce92619bd1e4807ec07eb55aed76e Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 17 May 2021 17:35:06 -0400 Subject: new configs - adaptive cache and cache write ratio --- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 2 ++ configs/tested-cfgs/SM7_QV100/gpgpusim.config | 6 ++++++ configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 3 +++ src/abstract_hardware_model.h | 2 ++ src/gpgpu-sim/gpu-cache.h | 5 +++++ src/gpgpu-sim/gpu-sim.cc | 7 +++++++ 6 files changed, 25 insertions(+) (limited to 'src') diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index 6189dca..e006085 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -110,6 +110,8 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_shmem_option 0,8,16,32,64,100 +-gpgpu_unified_l1d_size 128 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives us 3MB L2 cache -gpgpu_cache:dl2 S:64:128:16,L:B:m:L:P,A:192:4,32:0,32 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index bc5677c..043fce6 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -124,6 +124,9 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache -gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 @@ -203,3 +206,6 @@ #-trace_components WARP_SCHEDULER,SCOREBOARD #-trace_sampling_core 0 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 \ No newline at end of file diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 3fa51ee..1f0c15f 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -125,6 +125,9 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 +-gpgpu_cache_write_ratio 25 +-gpgpu_shmem_option 0,12,24,48,96 +-gpgpu_unified_l1d_size 128 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 4.5MB L2 cache -gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 982e416..e796571 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -373,6 +373,8 @@ class core_config { } unsigned mem_warp_parts; mutable unsigned gpgpu_shmem_size; + char *gpgpu_shmem_option; + unsigned gpgpu_unified_l1d_size; unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 00c09ae..ccc935b 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -491,6 +491,7 @@ class cache_config { m_data_port_width = 0; m_set_index_function = LINEAR_SET_FUNCTION; m_is_streaming = false; + m_wr_percent = 0; } void init(char *config, FuncCache status) { cache_status = status; @@ -754,6 +755,10 @@ class cache_config { char *m_config_stringPrefL1; char *m_config_stringPrefShared; FuncCache cache_status; + unsigned m_wr_percent; + write_allocate_policy_t get_write_allocate_policy() { + return m_write_alloc_policy; + } protected: void exit_parse_error() { diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index fd36e00..bd09cdb 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -249,6 +249,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); + option_parser_register(opp,"-gpgpu_cache_write_ratio",OPT_UINT32,&m_L1D_config.m_wr_percent,"L1D write ratio","0"); option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, "The number of L1 cache banks", "1"); @@ -326,6 +327,12 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register( opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size, "Size of shared memory per shader core (default 16kB)", "16384"); + option_parser_register( + opp, "-gpgpu_shmem_option", OPT_CSTR, &gpgpu_shmem_option, + "Option list of shared memory sizes", "0"); + option_parser_register( + opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &gpgpu_unified_l1d_size, + "Size of unified data cache(L1D + shared memory) in KB", "0"); option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_BOOL, &adaptive_cache_config, "adaptive_cache_config", "0"); option_parser_register( -- cgit v1.3 From a2b1b1c2839fe3fc05a0cae126204120fab00f62 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Mon, 17 May 2021 17:35:53 -0400 Subject: adaptive cache - update --- src/abstract_hardware_model.h | 2 +- src/gpgpu-sim/gpu-cache.h | 11 +++++ src/gpgpu-sim/shader.cc | 95 +++++++++++++++++++++++++------------------ 3 files changed, 68 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index e796571..bd10a93 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -65,7 +65,7 @@ enum FuncCache { FuncCachePreferL1 = 2 }; -enum AdaptiveCache { FIXED = 0, ADAPTIVE_VOLTA = 1 }; +enum AdaptiveCache { FIXED = 0, ADAPTIVE_CACHE = 1 }; #ifdef __cplusplus diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index ccc935b..0162b6c 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -616,6 +616,8 @@ class cache_config { m_atom_sz = (m_cache_type == SECTOR) ? SECTOR_SIZE : m_line_sz; m_sector_sz_log2 = LOGB2(SECTOR_SIZE); original_m_assoc = m_assoc; + original_sz = m_nset * original_m_assoc * m_line_sz; + // For more details about difference between FETCH_ON_WRITE and WRITE // VALIDAE policies Read: Jouppi, Norman P. "Cache write policies and @@ -710,6 +712,14 @@ class cache_config { assert(m_valid); return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc; } + unsigned get_original_assoc() const { + assert(m_valid); + return original_m_assoc; + } + unsigned get_original_sz() const { + assert(m_valid); + return original_sz; + } void print(FILE *fp) const { fprintf(fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", m_line_sz * m_nset * m_assoc, m_nset, m_assoc, m_line_sz); @@ -777,6 +787,7 @@ class cache_config { unsigned m_atom_sz; unsigned m_sector_sz_log2; unsigned original_m_assoc; + unsigned original_sz; bool m_is_streaming; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 14d9044..b2adb4f 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3292,50 +3292,67 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { if (adaptive_cache_config && !k.cache_config_set) { // For more info about adaptive cache, see // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x - unsigned total_shmed = kernel_info->smem * result; - assert(total_shmed >= 0 && total_shmed <= gpgpu_shmem_size); - // assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared - // assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets - if (total_shmed < gpgpu_shmem_size) { - switch (adaptive_cache_config) { - case FIXED: - break; - case ADAPTIVE_VOLTA: { - // For Volta, we assign the remaining shared memory to L1 cache - // For more info about adaptive cache, see - // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x - // assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared - - // To Do: make it flexible and not tuned to 9KB share memory - unsigned max_assoc = m_L1D_config.get_max_assoc(); - if (total_shmed == 0) - m_L1D_config.set_assoc(max_assoc); // L1 is 128KB and shd=0 - else if (total_shmed > 0 && total_shmed <= 8192) - m_L1D_config.set_assoc(0.9375 * - max_assoc); // L1 is 120KB and shd=8KB - else if (total_shmed > 8192 && total_shmed <= 16384) - m_L1D_config.set_assoc(0.875 * - max_assoc); // L1 is 112KB and shd=16KB - else if (total_shmed > 16384 && total_shmed <= 32768) - m_L1D_config.set_assoc(0.75 * max_assoc); // L1 is 96KB and - // shd=32KB - else if (total_shmed > 32768 && total_shmed <= 65536) - m_L1D_config.set_assoc(0.5 * max_assoc); // L1 is 64KB and shd=64KB - else if (total_shmed > 65536 && total_shmed <= gpgpu_shmem_size) - m_L1D_config.set_assoc(0.25 * max_assoc); // L1 is 32KB and - // shd=96KB - else - assert(0); - break; + std::vector shmem_list; + for (unsigned i = 0; i < strlen(gpgpu_shmem_option); i++) { + char option[4]; + int j = 0; + while (gpgpu_shmem_option[i] != ',' && i < strlen(gpgpu_shmem_option)) { + if (gpgpu_shmem_option[i] == ' ') { + // skip spaces + i++; + } else { + if (!isdigit(gpgpu_shmem_option[i])) { + // check for non digits, which should not be here + assert(0 && "invalid config: -gpgpu_shmem_option"); + } + option[j] = gpgpu_shmem_option[i]; + j++; + i++; } - default: - assert(0); } + // convert KB -> B + shmem_list.push_back((unsigned)atoi(option) * 1024); + } - printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", - m_L1D_config.get_total_size_inKB()); + unsigned total_shmem = kernel_info->smem * result; + unsigned total_unified = gpgpu_unified_l1d_size * 1024; + std::sort(shmem_list.begin(), shmem_list.end()); + + assert(total_shmem >= 0 && total_shmem <= shmem_list.back()); + switch (adaptive_cache_config) { + case FIXED: + break; + case ADAPTIVE_CACHE: { + // For more info about adaptive cache, see + bool l1d_configured = false; + unsigned l1_defined = m_L1D_config.get_original_sz() / 1024; + unsigned max_assoc = m_L1D_config.get_original_assoc() * + gpgpu_unified_l1d_size / l1_defined; + + if (total_shmem == 0) { + m_L1D_config.set_assoc(max_assoc); + l1d_configured = true; + } else { + for (std::vector::iterator it = shmem_list.begin(); + it < shmem_list.end() - 1; it++) { + if (total_shmem > *it && total_shmem <= *(it + 1)) { + float l1_ratio = 1 - (float) *(it + 1) / total_unified; + m_L1D_config.set_assoc(max_assoc * l1_ratio); + l1d_configured = true; + break; + } + } + } + assert(l1d_configured && "no shared memory option found"); + break; + } + default: + assert(0); } + printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", + m_L1D_config.get_total_size_inKB()); + k.cache_config_set = true; } -- cgit v1.3 From f70f5d6e5599c643074b0d00d3e3dcc385e5913d Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 15:10:51 -0400 Subject: re-wording/formatting --- src/gpgpu-sim/gpu-cache.cc | 17 ++++++++--------- src/gpgpu-sim/gpu-cache.h | 6 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') 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 4a762a933a054b5124fa46a12789ea98f5e2411d Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 15:22:31 -0400 Subject: formatting again --- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 4 ++-- configs/tested-cfgs/SM7_QV100/gpgpusim.config | 8 ++------ configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 2 +- src/gpgpu-sim/gpu-sim.cc | 2 +- src/gpgpu-sim/shader.cc | 1 + 5 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index e006085..d7573ab 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -100,6 +100,8 @@ # ::,::::,::,:** # ** Optional parameter - Required when mshr_type==Texture Fifo -gpgpu_adaptive_cache_config 0 +-gpgpu_shmem_option 0,8,16,32,64,100 +-gpgpu_unified_l1d_size 128 -gpgpu_l1_banks 4 -gpgpu_cache:dl1 S:1:128:512,L:L:m:N:L,A:512:8,16:0,32 -gpgpu_shmem_size 65536 @@ -110,8 +112,6 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 --gpgpu_shmem_option 0,8,16,32,64,100 --gpgpu_unified_l1d_size 128 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives us 3MB L2 cache -gpgpu_cache:dl2 S:64:128:16,L:B:m:L:P,A:192:4,32:0,32 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index 043fce6..59c7f43 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -124,7 +124,7 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 --gpgpu_cache_write_ratio 25 +-gpgpu_l1_cache_write_ratio 25 -gpgpu_shmem_option 0,12,24,48,96 -gpgpu_unified_l1d_size 128 @@ -204,8 +204,4 @@ # tracing functionality #-trace_enabled 1 #-trace_components WARP_SCHEDULER,SCOREBOARD -#-trace_sampling_core 0 - --gpgpu_cache_write_ratio 25 --gpgpu_shmem_option 0,12,24,48,96 --gpgpu_unified_l1d_size 128 \ No newline at end of file +#-trace_sampling_core 0 \ No newline at end of file diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 1f0c15f..3e080bc 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -125,7 +125,7 @@ -gpgpu_l1_latency 20 -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 --gpgpu_cache_write_ratio 25 +-gpgpu_l1_cache_write_ratio 25 -gpgpu_shmem_option 0,12,24,48,96 -gpgpu_unified_l1d_size 128 diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index bd09cdb..a2aa929 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -249,7 +249,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); - option_parser_register(opp,"-gpgpu_cache_write_ratio",OPT_UINT32,&m_L1D_config.m_wr_percent,"L1D write ratio","0"); + option_parser_register(opp,"-gpgpu_l1_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"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index b2adb4f..141c700 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3326,6 +3326,7 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { // For more info about adaptive cache, see bool l1d_configured = false; unsigned l1_defined = m_L1D_config.get_original_sz() / 1024; + assert(gpgpu_unified_l1d_size % l1_defined == 0); unsigned max_assoc = m_L1D_config.get_original_assoc() * gpgpu_unified_l1d_size / l1_defined; -- 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') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 05b338e..98951ca 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -279,17 +279,19 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, } } if (!line->is_reserved_line()) { + // percentage of dirty lines in the cache + // number of dirty lines / total lines in the cache + float dirty_line_percentage = + (float) (m_dirty / (m_config.m_nset * m_config.m_assoc )) * 100; if (!line->is_modified_line() || - m_dirty / (m_config.m_nset * m_config.m_assoc * 100) >= - m_config.m_wr_percent) { + dirty_line_percentage >= m_config.m_wr_percent) { + // if number of dirty lines in the cache is greater than + // a specific value all_reserved = false; if (line->is_invalid_line()) { invalid_line = index; } else { // valid line : keep track of most appropriate replacement candidate - - // don't evict write until dirty lines reach threshold - // make sure at least 1 candidate is assigned if (m_config.m_replacement_policy == LRU) { if (line->get_last_access_time() < valid_timestamp) { valid_timestamp = line->get_last_access_time(); @@ -363,7 +365,7 @@ enum cache_request_status tag_array::access(new_addr_type addr, unsigned time, m_lines[idx]->set_byte_mask(mf); evicted.set_info(m_lines[idx]->m_block_addr, m_lines[idx]->get_modified_size(), - m_lines[idx]->get_byte_mask(), + m_lines[idx]->get_dirty_byte_mask(), m_lines[idx]->get_dirty_sector_mask()); m_dirty--; } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 5179173..dc3b39a 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -135,7 +135,7 @@ struct cache_block_t { mem_access_sector_mask_t sector_mask) = 0; virtual void set_byte_mask(mem_fetch *mf) = 0; virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) = 0; - virtual mem_access_byte_mask_t get_byte_mask() = 0; + virtual mem_access_byte_mask_t get_dirty_byte_mask() = 0; virtual mem_access_sector_mask_t get_dirty_sector_mask() = 0; virtual unsigned long long get_last_access_time() = 0; virtual void set_last_access_time(unsigned long long time, @@ -215,7 +215,7 @@ struct line_cache_block : public cache_block_t { virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) { m_byte_mask = m_byte_mask | byte_mask; } - virtual mem_access_byte_mask_t get_byte_mask() { + virtual mem_access_byte_mask_t get_dirty_byte_mask() { return m_byte_mask; } virtual mem_access_sector_mask_t get_dirty_sector_mask() { @@ -410,7 +410,7 @@ struct sector_cache_block : public cache_block_t { virtual void set_byte_mask(mem_access_byte_mask_t byte_mask) { m_byte_mask = m_byte_mask | byte_mask; } - virtual mem_access_byte_mask_t get_byte_mask() { + virtual mem_access_byte_mask_t get_dirty_byte_mask() { return m_byte_mask; } virtual mem_access_sector_mask_t get_dirty_sector_mask() { -- cgit v1.3 From f27da224f3e468d600499a9d3619009ed9c70256 Mon Sep 17 00:00:00 2001 From: JRPAN <25518778+JRPan@users.noreply.github.com> Date: Wed, 19 May 2021 17:27:43 -0400 Subject: Use cache config multipilier when possible --- src/abstract_hardware_model.h | 1 - src/gpgpu-sim/gpu-cache.h | 28 +++++++++++++++------------- src/gpgpu-sim/gpu-sim.cc | 2 +- src/gpgpu-sim/shader.cc | 8 +++----- 4 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index bd10a93..dbe138a 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -374,7 +374,6 @@ class core_config { unsigned mem_warp_parts; mutable unsigned gpgpu_shmem_size; char *gpgpu_shmem_option; - unsigned gpgpu_unified_l1d_size; unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 0162b6c..87a6b13 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -512,6 +512,14 @@ class cache_config { exit_parse_error(); } + // set * assoc * cacheline size. Then convert Byte to KB + unsigned original_size = m_nset * m_assoc * m_line_sz / 1024; + if (m_unified_cache_size > 0) { + max_cache_multiplier = m_unified_cache_size / original_size; + } else { + max_cache_multiplier = MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; + } + switch (ct) { case 'N': m_cache_type = NORMAL; @@ -588,7 +596,7 @@ class cache_config { // https://ieeexplore.ieee.org/document/8344474/ m_is_streaming = true; m_alloc_policy = ON_FILL; - m_mshr_entries = m_nset * m_assoc * MAX_DEFAULT_CACHE_SIZE_MULTIBLIER; + m_mshr_entries = m_nset * m_assoc * max_cache_multiplier; if (m_cache_type == SECTOR) m_mshr_entries *= SECTOR_CHUNCK_SIZE; m_mshr_max_merge = MAX_WARP_PER_SM; } @@ -616,7 +624,6 @@ class cache_config { m_atom_sz = (m_cache_type == SECTOR) ? SECTOR_SIZE : m_line_sz; m_sector_sz_log2 = LOGB2(SECTOR_SIZE); original_m_assoc = m_assoc; - original_sz = m_nset * original_m_assoc * m_line_sz; // For more details about difference between FETCH_ON_WRITE and WRITE @@ -706,19 +713,13 @@ class cache_config { } unsigned get_max_num_lines() const { assert(m_valid); - return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * m_nset * original_m_assoc; + // gpgpu_unified_cache_size is in KB while original_sz is in B + return max_cache_multiplier * m_nset * original_m_assoc; } unsigned get_max_assoc() const { assert(m_valid); - return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc; - } - unsigned get_original_assoc() const { - assert(m_valid); - return original_m_assoc; - } - unsigned get_original_sz() const { - assert(m_valid); - return original_sz; + // gpgpu_unified_cache_size is in KB while original_sz is in B + return max_cache_multiplier * original_m_assoc; } void print(FILE *fp) const { fprintf(fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", @@ -766,6 +767,7 @@ class cache_config { char *m_config_stringPrefShared; FuncCache cache_status; unsigned m_wr_percent; + unsigned m_unified_cache_size; write_allocate_policy_t get_write_allocate_policy() { return m_write_alloc_policy; } @@ -787,8 +789,8 @@ class cache_config { unsigned m_atom_sz; unsigned m_sector_sz_log2; unsigned original_m_assoc; - unsigned original_sz; bool m_is_streaming; + unsigned max_cache_multiplier; enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO enum write_policy_t diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a2aa929..df30047 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -331,7 +331,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { opp, "-gpgpu_shmem_option", OPT_CSTR, &gpgpu_shmem_option, "Option list of shared memory sizes", "0"); option_parser_register( - opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &gpgpu_unified_l1d_size, + opp, "-gpgpu_unified_l1d_size", OPT_UINT32, &m_L1D_config.m_unified_cache_size, "Size of unified data cache(L1D + shared memory) in KB", "0"); option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_BOOL, &adaptive_cache_config, "adaptive_cache_config", "0"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 141c700..3efef2b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3315,7 +3315,8 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { } unsigned total_shmem = kernel_info->smem * result; - unsigned total_unified = gpgpu_unified_l1d_size * 1024; + // Unified cache config is in KB. Converting to B + unsigned total_unified = m_L1D_config.m_unified_cache_size * 1024; std::sort(shmem_list.begin(), shmem_list.end()); assert(total_shmem >= 0 && total_shmem <= shmem_list.back()); @@ -3325,10 +3326,7 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { case ADAPTIVE_CACHE: { // For more info about adaptive cache, see bool l1d_configured = false; - unsigned l1_defined = m_L1D_config.get_original_sz() / 1024; - assert(gpgpu_unified_l1d_size % l1_defined == 0); - unsigned max_assoc = m_L1D_config.get_original_assoc() * - gpgpu_unified_l1d_size / l1_defined; + unsigned max_assoc = m_L1D_config.get_max_assoc(); if (total_shmem == 0) { m_L1D_config.set_assoc(max_assoc); -- cgit v1.3