summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/tested-cfgs/SM7_TITANV/gpgpusim.config2
-rw-r--r--src/gpgpu-sim/gpu-cache.cc13
-rw-r--r--src/gpgpu-sim/gpu-cache.h41
-rw-r--r--src/gpgpu-sim/shader.cc71
4 files changed, 78 insertions, 49 deletions
diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
index 3e080bc..32245d7 100644
--- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
+++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
@@ -116,7 +116,7 @@
-gpgpu_adaptive_cache_config 1
# Volta unified cache has four banks
-gpgpu_l1_banks 4
--gpgpu_cache:dl1 S:1:128:256,L:L:s:N:L,A:256:8,16:0,32
+-gpgpu_cache:dl1 S:1:128:256,L:L:m:N:L,A:512:8,16:0,32
-gpgpu_shmem_size 98304
-gpgpu_shmem_sizeDefault 98304
-gpgpu_shmem_per_block 65536
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 98951ca..297a94c 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -321,15 +321,6 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
abort(); // if an unreserved block exists, it is either invalid or
// replaceable
- if (probe_mode && m_config.is_streaming()) {
- line_table::const_iterator i =
- pending_lines.find(m_config.block_addr(addr));
- assert(mf);
- if (!mf->is_write() && i != pending_lines.end()) {
- if (i->second != mf->get_inst().get_uid()) return SECTOR_MISS;
- }
- }
-
return MISS;
}
@@ -1091,7 +1082,6 @@ void baseline_cache::fill(mem_fetch *mf, unsigned time) {
m_tag_array->fill(e->second.m_cache_index, time, mf);
else if (m_config.m_alloc_policy == ON_FILL) {
m_tag_array->fill(e->second.m_block_addr, time, mf, mf->is_write());
- if (m_config.is_streaming()) m_tag_array->remove_pending_line(mf);
} else
abort();
bool has_atomic = false;
@@ -1171,9 +1161,6 @@ void baseline_cache::send_read_request(new_addr_type addr,
m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf);
m_mshrs.add(mshr_addr, mf);
- if (m_config.is_streaming() && m_config.m_cache_type == SECTOR) {
- m_tag_array->add_pending_line(mf);
- }
m_extra_mf_fields[mf] = extra_mf_fields(
mshr_addr, mf->get_addr(), cache_index, mf->get_data_size(), m_config);
mf->set_data_size(m_config.get_atom_sz());
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 578fadb..75dce40 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -647,22 +647,26 @@ class cache_config {
exit_parse_error();
}
if (m_alloc_policy == STREAMING) {
- // For streaming cache, we set the alloc policy to be on-fill to remove
- // all line_alloc_fail stalls we set the MSHRs to be equal to max
- // allocated cache lines. This is possible by moving TAG to be shared
- // between cache line and MSHR enrty (i.e. for each cache line, there is
- // an MSHR rntey associated with it) This is the easiest think we can
- // think about to model (mimic) L1 streaming cache in Pascal and Volta
- // Based on our microbenchmakrs, MSHRs entries have been increasing
- // substantially in Pascal and Volta For more information about streaming
- // cache, see:
- // http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf
- // https://ieeexplore.ieee.org/document/8344474/
+ /*
+ For streaming cache:
+ (1) we set the alloc policy to be on-fill to remove all line_alloc_fail stalls.
+ if the whole memory is allocated to the L1 cache, then make the allocation to be on_MISS
+ otherwise, make it ON_FILL to eliminate line allocation fails.
+ i.e. MSHR throughput is the same, independent on the L1 cache size/associativity
+ So, we set the allocation policy per kernel basis, see shader.cc, max_cta() function
+
+ (2) We also set the MSHRs to be equal to max
+ allocated cache lines. This is possible by moving TAG to be shared
+ between cache line and MSHR enrty (i.e. for each cache line, there is
+ an MSHR rntey associated with it). This is the easiest think we can
+ think of to model (mimic) L1 streaming cache in Pascal and Volta
+
+ For more information about streaming cache, see:
+ http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf
+ https://ieeexplore.ieee.org/document/8344474/
+ */
m_is_streaming = true;
m_alloc_policy = ON_FILL;
- m_mshr_entries = m_nset * m_assoc * max_cache_multiplier;
- if (m_cache_type == SECTOR) m_mshr_entries *= SECTOR_CHUNCK_SIZE;
- m_mshr_max_merge = MAX_WARP_PER_SM;
}
switch (mshr_type) {
case 'F':
@@ -712,7 +716,8 @@ class cache_config {
}
// detect invalid configuration
- if (m_alloc_policy == ON_FILL and m_write_policy == WRITE_BACK) {
+ if ((m_alloc_policy == ON_FILL || m_alloc_policy == STREAMING)
+ and m_write_policy == WRITE_BACK) {
// A writeback cache with allocate-on-fill policy will inevitably lead to
// deadlock: The deadlock happens when an incoming cache-fill evicts a
// dirty line, generating a writeback request. If the memory subsystem is
@@ -758,6 +763,9 @@ class cache_config {
case 'L':
m_set_index_function = LINEAR_SET_FUNCTION;
break;
+ case 'X':
+ m_set_index_function = BITWISE_XORING_FUNCTION;
+ break;
default:
exit_parse_error();
}
@@ -826,6 +834,9 @@ class cache_config {
}
bool is_streaming() { return m_is_streaming; }
FuncCache get_cache_status() { return cache_status; }
+ void set_allocation_policy(enum allocation_policy_t alloc) {
+ m_alloc_policy = alloc;
+ }
char *m_config_string;
char *m_config_stringPrefL1;
char *m_config_stringPrefShared;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 3d352c9..db53fca 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -123,7 +123,7 @@ void shader_core_ctx::create_front_pipeline() {
if (m_config->sub_core_model) {
// in subcore model, each scheduler should has its own issue register, so
- // num scheduler = reg width
+ // ensure num scheduler = reg width
assert(m_config->gpgpu_num_sched_per_core ==
m_pipeline_reg[ID_OC_SP].get_size());
assert(m_config->gpgpu_num_sched_per_core ==
@@ -139,6 +139,11 @@ void shader_core_ctx::create_front_pipeline() {
if (m_config->gpgpu_num_int_units > 0)
assert(m_config->gpgpu_num_sched_per_core ==
m_pipeline_reg[ID_OC_INT].get_size());
+ for (int j = 0; j < m_config->m_specialized_unit.size(); j++) {
+ if (m_config->m_specialized_unit[j].num_units > 0)
+ assert(m_config->gpgpu_num_sched_per_core ==
+ m_config->m_specialized_unit[j].id_oc_spec_reg_width);
+ }
}
m_threadState = (thread_ctx_t *)calloc(sizeof(thread_ctx_t),
@@ -1240,22 +1245,6 @@ void scheduler_unit::cycle() {
previous_issued_inst_exec_type = exec_unit_type_t::MEM;
}
} else {
- bool sp_pipe_avail =
- (m_shader->m_config->gpgpu_num_sp_units > 0) &&
- m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id);
- bool sfu_pipe_avail =
- (m_shader->m_config->gpgpu_num_sfu_units > 0) &&
- m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id);
- bool tensor_core_pipe_avail =
- (m_shader->m_config->gpgpu_num_tensor_core_units > 0) &&
- m_tensor_core_out->has_free(
- m_shader->m_config->sub_core_model, m_id);
- bool dp_pipe_avail =
- (m_shader->m_config->gpgpu_num_dp_units > 0) &&
- m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id);
- bool int_pipe_avail =
- (m_shader->m_config->gpgpu_num_int_units > 0) &&
- m_int_out->has_free(m_shader->m_config->sub_core_model, m_id);
// This code need to be refactored
if (pI->op != TENSOR_CORE_OP && pI->op != SFU_OP &&
@@ -1263,6 +1252,13 @@ void scheduler_unit::cycle() {
bool execute_on_SP = false;
bool execute_on_INT = false;
+ bool sp_pipe_avail =
+ (m_shader->m_config->gpgpu_num_sp_units > 0) &&
+ m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id);
+ bool int_pipe_avail =
+ (m_shader->m_config->gpgpu_num_int_units > 0) &&
+ m_int_out->has_free(m_shader->m_config->sub_core_model, m_id);
+
// if INT unit pipline exist, then execute ALU and INT
// operations on INT unit and SP-FPU on SP unit (like in Volta)
// if INT unit pipline does not exist, then execute all ALU, INT
@@ -1323,6 +1319,11 @@ void scheduler_unit::cycle() {
(pI->op == DP_OP) &&
!(diff_exec_units && previous_issued_inst_exec_type ==
exec_unit_type_t::DP)) {
+
+ bool dp_pipe_avail =
+ (m_shader->m_config->gpgpu_num_dp_units > 0) &&
+ m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id);
+
if (dp_pipe_avail) {
m_shader->issue_warp(*m_dp_out, pI, active_mask, warp_id,
m_id);
@@ -1338,6 +1339,11 @@ void scheduler_unit::cycle() {
(pI->op == SFU_OP) || (pI->op == ALU_SFU_OP)) &&
!(diff_exec_units && previous_issued_inst_exec_type ==
exec_unit_type_t::SFU)) {
+
+ bool sfu_pipe_avail =
+ (m_shader->m_config->gpgpu_num_sfu_units > 0) &&
+ m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id);
+
if (sfu_pipe_avail) {
m_shader->issue_warp(*m_sfu_out, pI, active_mask, warp_id,
m_id);
@@ -1349,6 +1355,12 @@ void scheduler_unit::cycle() {
} else if ((pI->op == TENSOR_CORE_OP) &&
!(diff_exec_units && previous_issued_inst_exec_type ==
exec_unit_type_t::TENSOR)) {
+
+ bool tensor_core_pipe_avail =
+ (m_shader->m_config->gpgpu_num_tensor_core_units > 0) &&
+ m_tensor_core_out->has_free(
+ m_shader->m_config->sub_core_model, m_id);
+
if (tensor_core_pipe_avail) {
m_shader->issue_warp(*m_tensor_core_out, pI, active_mask,
warp_id, m_id);
@@ -1581,7 +1593,10 @@ void swl_scheduler::order_warps() {
}
}
-void shader_core_ctx::read_operands() {}
+void shader_core_ctx::read_operands() {
+ for (int i = 0; i < m_config->reg_file_port_throughput; ++i)
+ m_operand_collector.step();
+}
address_type coalesced_segment(address_type addr,
unsigned segment_size_lg2bytes) {
@@ -2606,8 +2621,7 @@ inst->space.get_type() != shared_space) { unsigned warp_id = inst->warp_id();
*/
void ldst_unit::cycle() {
writeback();
- for (int i = 0; i < m_config->reg_file_port_throughput; ++i)
- m_operand_collector->step();
+
for (unsigned stage = 0; (stage + 1) < m_pipeline_depth; stage++)
if (m_pipeline_reg[stage]->empty() && !m_pipeline_reg[stage + 1]->empty())
move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage + 1]);
@@ -3377,8 +3391,25 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const {
assert(0);
}
+<<<<<<< HEAD
+ if(m_L1D_config.is_streaming()) {
+ //for streaming cache, if the whole memory is allocated
+ //to the L1 cache, then make the allocation to be on_MISS
+ //otherwise, make it ON_FILL to eliminate line allocation fails
+ //i.e. MSHR throughput is the same, independent on the L1 cache size/associativity
+ if(total_shmed == 0) {
+ m_L1D_config.set_allocation_policy(ON_MISS);
+ printf("GPGPU-Sim: Reconfigure L1 allocation to ON_MISS\n");
+ }
+ else {
+ m_L1D_config.set_allocation_policy(ON_FILL);
+ printf("GPGPU-Sim: Reconfigure L1 allocation to ON_FILL\n");
+ }
+ }
+=======
printf("GPGPU-Sim: Reconfigure L1 cache to %uKB\n",
m_L1D_config.get_total_size_inKB());
+>>>>>>> 2b2b6a2916e4ed833c707be887bf927167a71fa6
k.cache_config_set = true;
}