summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormkhairy <[email protected]>2021-05-19 17:51:00 -0400
committerGitHub <[email protected]>2021-05-19 17:51:00 -0400
commit2b2b6a2916e4ed833c707be887bf927167a71fa6 (patch)
tree526646c9ac3f182e9fd7103255e3680f2fcc7adc
parent0e4f12ae3fefd6bad6175014411a6587a3898ac8 (diff)
parent1875132a20422404ea75d04fc7be58a1bbca48f3 (diff)
Merge pull request #15 from JRPan/adaptive-cache
Adaptive cache
-rw-r--r--configs/tested-cfgs/SM75_RTX2060/gpgpusim.config2
-rw-r--r--configs/tested-cfgs/SM7_QV100/gpgpusim.config6
-rw-r--r--configs/tested-cfgs/SM7_TITANV/gpgpusim.config3
-rw-r--r--src/abstract_hardware_model.h3
-rw-r--r--src/gpgpu-sim/gpu-cache.h21
-rw-r--r--src/gpgpu-sim/gpu-sim.cc7
-rw-r--r--src/gpgpu-sim/shader.cc94
7 files changed, 91 insertions, 45 deletions
diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config
index 6189dca..d7573ab 100644
--- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config
+++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config
@@ -100,6 +100,8 @@
# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry>
# ** 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
diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config
index bc5677c..59c7f43 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_l1_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
@@ -201,5 +204,4 @@
# tracing functionality
#-trace_enabled 1
#-trace_components WARP_SCHEDULER,SCOREBOARD
-#-trace_sampling_core 0
-
+#-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 3fa51ee..3e080bc 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_l1_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 e09acdb..17a1cec 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
@@ -373,6 +373,7 @@ class core_config {
}
unsigned mem_warp_parts;
mutable unsigned gpgpu_shmem_size;
+ char *gpgpu_shmem_option;
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 dc3b39a..578fadb 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -555,6 +555,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;
@@ -575,6 +576,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;
@@ -651,7 +660,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;
}
@@ -680,6 +689,7 @@ class cache_config {
m_sector_sz_log2 = LOGB2(SECTOR_SIZE);
original_m_assoc = m_assoc;
+
// For more details about difference between FETCH_ON_WRITE and WRITE
// VALIDAE policies Read: Jouppi, Norman P. "Cache write policies and
// performance". ISCA 93. WRITE_ALLOCATE is the old write policy in
@@ -767,11 +777,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;
+ // 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",
@@ -818,6 +830,8 @@ class cache_config {
char *m_config_stringPrefL1;
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;
}
@@ -843,6 +857,7 @@ class cache_config {
unsigned m_sector_sz_log2;
unsigned original_m_assoc;
bool m_is_streaming;
+ unsigned max_cache_multiplier;
enum replacement_policy_t m_replacement_policy; // 'L' = LRU, 'F' = FIFO
enum write_policy_t
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index fd36e00..df30047 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) {
" {<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_"
"alloc>,<mshr>:<N>:<merge>,<mq> | 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_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, &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");
option_parser_register(
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 22bd8e9..3d352c9 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -3320,50 +3320,66 @@ 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<unsigned> 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);
+ }
+
+ unsigned total_shmem = kernel_info->smem * result;
+ // Unified cache config is in KB. Converting to B
+ unsigned total_unified = m_L1D_config.m_unified_cache_size * 1024;
+ std::sort(shmem_list.begin(), shmem_list.end());
+
+ assert(total_shmem >= 0 && total_shmem <= shmem_list.back());
+ switch (adaptive_cache_config) {
+ case FIXED:
+ break;
+ case ADAPTIVE_CACHE: {
+ // For more info about adaptive cache, see
+ bool l1d_configured = false;
+ unsigned max_assoc = m_L1D_config.get_max_assoc();
- printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n",
- m_L1D_config.get_total_size_inKB());
+ if (total_shmem == 0) {
+ m_L1D_config.set_assoc(max_assoc);
+ l1d_configured = true;
+ } else {
+ for (std::vector<unsigned>::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;
}