diff options
| author | Wilson Fung <[email protected]> | 2012-10-30 22:43:44 -0800 |
|---|---|---|
| committer | Andrew Boktor <[email protected]> | 2014-08-14 13:49:21 -0700 |
| commit | d0b377ded0c804580a78f2327b84e6e2ea1ee069 (patch) | |
| tree | cc14f8b6a599b86e5da351c66eee5ab40962da56 | |
| parent | 3863ad27814eefe2d26b2eba7eb8a4ab65bef5a4 (diff) | |
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]
| -rw-r--r-- | CHANGES | 3 | ||||
| -rw-r--r-- | configs/GTX480/gpgpusim.config | 25 | ||||
| -rw-r--r-- | configs/TeslaC2050/gpgpusim.config | 31 | ||||
| -rw-r--r-- | src/abstract_hardware_model.cc | 94 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 6 |
6 files changed, 96 insertions, 65 deletions
@@ -57,6 +57,9 @@ Version 3.1.1+edits (development branch) versus 3.1.1 simulation thread. - Fixed clCreateProgramWithSource to accept NULL or 0 as string length parameter - Fixed replacement of printf modifiers when compiling OpenCL code (e.g. '%f') + - Fixed the shared memory bank conflict model for GTX 480 and Tesla C2050. + Added options to configure the number of shared memory banks per shader + core and to allow a more flexible broadcast mechanism. Version 3.1.1 versus 3.1.0 - Add checks to top level makefile to ensure setup_environment is run and checks to diff --git a/configs/GTX480/gpgpusim.config b/configs/GTX480/gpgpusim.config index fd23e57..abd9627 100644 --- a/configs/GTX480/gpgpusim.config +++ b/configs/GTX480/gpgpusim.config @@ -3,6 +3,11 @@ -gpgpu_ptx_sim_mode 0 -gpgpu_ptx_force_max_capability 20 + +# SASS execution (only supported with CUDA >= 4.0) +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + # high level architecture configuration -gpgpu_n_clusters 15 -gpgpu_n_cores_per_cluster 1 @@ -37,6 +42,7 @@ -ptx_opcode_latency_dp 8,19,8,8,330 -ptx_opcode_initiation_dp 8,16,8,8,130 + # In Fermi, the cache and shared memory can be configured to 16kb:48kb(default) or 48kb:16kb # <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo @@ -55,8 +61,16 @@ -gpgpu_tex_cache:l1 4:128:24,L:R:m:N,F:128:4,128:2 -gpgpu_const_cache:l1 64:64:2,L:R:f:N,A:2:32,4 +# enable operand collector +-gpgpu_operand_collector_num_units_sp 6 +-gpgpu_operand_collector_num_units_sfu 8 +-gpgpu_operand_collector_num_in_ports_sp 2 +-gpgpu_operand_collector_num_out_ports_sp 2 -gpgpu_num_reg_banks 16 +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 -gpgpu_shmem_warp_parts 1 -gpgpu_max_insn_issue_per_warp 1 @@ -97,14 +111,5 @@ -gpgpu_memlatency_stat 14 -gpgpu_runtime_stat 500 -enable_ptx_file_line_stats 1 - -# SASS execution (only supported with CUDA >= 4.0) --gpgpu_ptx_convert_to_ptxplus 0 --gpgpu_ptx_save_converted_ptxplus 0 - -# enable operand collector --gpgpu_operand_collector_num_units_sp 6 --gpgpu_operand_collector_num_units_sfu 8 --gpgpu_operand_collector_num_in_ports_sp 2 --gpgpu_operand_collector_num_out_ports_sp 2 -visualizer_enabled 0 + diff --git a/configs/TeslaC2050/gpgpusim.config b/configs/TeslaC2050/gpgpusim.config index 86f0d85..4871378 100644 --- a/configs/TeslaC2050/gpgpusim.config +++ b/configs/TeslaC2050/gpgpusim.config @@ -3,6 +3,14 @@ -gpgpu_ptx_sim_mode 0 -gpgpu_ptx_force_max_capability 20 +# Using cuobjdump to extract ptx/SASS +#-gpgpu_ptx_use_cuobjdump 1 # use default + +# SASS execution (only supported with CUDA >= 4.0) +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + + # high level architecture configuration -gpgpu_n_clusters 14 -gpgpu_n_cores_per_cluster 1 @@ -56,8 +64,16 @@ -gpgpu_tex_cache:l1 4:128:24,L:R:m:N,F:128:4,128:2 -gpgpu_const_cache:l1 64:64:2,L:R:f:N,A:2:32,4 +# enable operand collector +-gpgpu_operand_collector_num_units_sp 6 +-gpgpu_operand_collector_num_units_sfu 8 +-gpgpu_operand_collector_num_in_ports_sp 2 +-gpgpu_operand_collector_num_out_ports_sp 2 -gpgpu_num_reg_banks 16 +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 -gpgpu_shmem_warp_parts 1 -gpgpu_max_insn_issue_per_warp 1 @@ -98,18 +114,5 @@ -gpgpu_memlatency_stat 14 -gpgpu_runtime_stat 500 -enable_ptx_file_line_stats 1 - -# Using cuobjdump to extract ptx/SASS --gpgpu_ptx_use_cuobjdump 1 - -# SASS execution (only supported with CUDA >= 4.0) --gpgpu_ptx_convert_to_ptxplus 0 --gpgpu_ptx_save_converted_ptxplus 0 - -# enable operand collector --gpgpu_operand_collector_num_units_sp 6 --gpgpu_operand_collector_num_units_sfu 8 --gpgpu_operand_collector_num_in_ports_sp 2 --gpgpu_operand_collector_num_out_ports_sp 2 -visualizer_enabled 0 --keep 1 + 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<unsigned,std::map<new_addr_type,unsigned> >::iterator b; - for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { - unsigned bank = b->first; - std::map<new_addr_type,unsigned> &access_set = b->second; - std::map<new_addr_type,unsigned>::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<new_addr_type,unsigned> &access_set = b->second; - std::map<new_addr_type,unsigned>::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<unsigned,std::map<new_addr_type,unsigned> >::iterator b; + for( b=bank_accs.begin(); b != bank_accs.end(); b++ ) { + unsigned bank = b->first; + std::map<new_addr_type,unsigned> &access_set = b->second; + std::map<new_addr_type,unsigned>::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<new_addr_type,unsigned> &access_set = b->second; + std::map<new_addr_type,unsigned>::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<unsigned,std::map<new_addr_type,unsigned> >::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"); |
