From d0b377ded0c804580a78f2327b84e6e2ea1ee069 Mon Sep 17 00:00:00 2001 From: Wilson Fung Date: Tue, 30 Oct 2012 22:43:44 -0800 Subject: Fixed the shared memory bank conflict model for GTX 480 and Tesla C2050. Now the two configs will feature 32-bank shared memory with a more flexible broadcast mechanism. [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 14509] --- src/abstract_hardware_model.cc | 94 ++++++++++++++++++++++++------------------ src/abstract_hardware_model.h | 2 + src/gpgpu-sim/gpu-sim.cc | 6 +++ 3 files changed, 61 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index a2539af..5605693 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -207,53 +207,65 @@ void warp_inst_t::generate_mem_accesses() bank_accs[bank][word]++; } - // step 2: look for and select a broadcast bank/word if one occurs - bool broadcast_detected = false; - new_addr_type broadcast_word=(new_addr_type)-1; - unsigned broadcast_bank=(unsigned)-1; - std::map >::iterator b; - for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { - unsigned bank = b->first; - std::map &access_set = b->second; - std::map::iterator w; - for( w=access_set.begin(); w != access_set.end(); ++w ) { - if( w->second > 1 ) { - // found a broadcast - broadcast_detected=true; - broadcast_bank=bank; - broadcast_word=w->first; - break; - } - } - if( broadcast_detected ) - break; - } - - // step 3: figure out max bank accesses performed, taking account of broadcast case - unsigned max_bank_accesses=0; - for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { - unsigned bank_accesses=0; - std::map &access_set = b->second; - std::map::iterator w; - for( w=access_set.begin(); w != access_set.end(); ++w ) - bank_accesses += w->second; - if( broadcast_detected && broadcast_bank == b->first ) { + if (m_config->shmem_limited_broadcast) { + // step 2: look for and select a broadcast bank/word if one occurs + bool broadcast_detected = false; + new_addr_type broadcast_word=(new_addr_type)-1; + unsigned broadcast_bank=(unsigned)-1; + std::map >::iterator b; + for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { + unsigned bank = b->first; + std::map &access_set = b->second; + std::map::iterator w; for( w=access_set.begin(); w != access_set.end(); ++w ) { - if( w->first == broadcast_word ) { - unsigned n = w->second; - assert(n > 1); // or this wasn't a broadcast - assert(bank_accesses >= (n-1)); - bank_accesses -= (n-1); + if( w->second > 1 ) { + // found a broadcast + broadcast_detected=true; + broadcast_bank=bank; + broadcast_word=w->first; break; } } + if( broadcast_detected ) + break; + } + + // step 3: figure out max bank accesses performed, taking account of broadcast case + unsigned max_bank_accesses=0; + for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { + unsigned bank_accesses=0; + std::map &access_set = b->second; + std::map::iterator w; + for( w=access_set.begin(); w != access_set.end(); ++w ) + bank_accesses += w->second; + if( broadcast_detected && broadcast_bank == b->first ) { + for( w=access_set.begin(); w != access_set.end(); ++w ) { + if( w->first == broadcast_word ) { + unsigned n = w->second; + assert(n > 1); // or this wasn't a broadcast + assert(bank_accesses >= (n-1)); + bank_accesses -= (n-1); + break; + } + } + } + if( bank_accesses > max_bank_accesses ) + max_bank_accesses = bank_accesses; } - if( bank_accesses > max_bank_accesses ) - max_bank_accesses = bank_accesses; - } - // step 4: accumulate - total_accesses+= max_bank_accesses; + // step 4: accumulate + total_accesses+= max_bank_accesses; + } else { + // step 2: look for the bank with the maximum number of access to different words + unsigned max_bank_accesses=0; + std::map >::iterator b; + for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { + max_bank_accesses = std::max(max_bank_accesses, (unsigned)b->second.size()); + } + + // step 3: accumulate + total_accesses+= max_bank_accesses; + } } assert( total_accesses > 0 && total_accesses <= m_config->warp_size ); cycles = total_accesses; // shared memory conflicts modeled as larger initiation interval diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 183123b..9681a67 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -186,6 +186,7 @@ struct core_config { { m_valid = false; num_shmem_bank=16; + shmem_limited_broadcast = false; } virtual void init() = 0; @@ -196,6 +197,7 @@ struct core_config { int gpgpu_coalesce_arch; // shared memory bank conflict checking parameters + bool shmem_limited_broadcast; static const address_type WORD_SIZE=4; unsigned num_shmem_bank; unsigned shmem_bank_func(address_type addr) const diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 9c8d327..6aeaa63 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -185,6 +185,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_num_banks", OPT_UINT32, &num_shmem_bank, + "Number of banks in the shared memory in each shader core (default 16)", + "16"); + option_parser_register(opp, "-gpgpu_shmem_limited_broadcast", OPT_BOOL, &shmem_limited_broadcast, + "Limit shared memory to do one broadcast per cycle (default on)", + "1"); option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, "Number of portions a warp is divided into for shared memory bank conflict check ", "2"); -- cgit v1.3