summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/addrdec.cc29
-rw-r--r--src/gpgpu-sim/addrdec.h5
-rw-r--r--src/gpgpu-sim/dram.cc82
-rw-r--r--src/gpgpu-sim/dram.h66
-rw-r--r--src/gpgpu-sim/dram_sched.cc14
-rw-r--r--src/gpgpu-sim/gpu-cache.cc29
-rw-r--r--src/gpgpu-sim/gpu-cache.h63
-rw-r--r--src/gpgpu-sim/gpu-sim.cc76
-rw-r--r--src/gpgpu-sim/gpu-sim.h35
-rw-r--r--src/gpgpu-sim/icnt_wrapper.cc90
-rw-r--r--src/gpgpu-sim/icnt_wrapper.h5
-rw-r--r--src/gpgpu-sim/l2cache.cc56
-rw-r--r--src/gpgpu-sim/l2cache.h13
-rw-r--r--src/gpgpu-sim/l2cache_trace.h4
-rw-r--r--src/gpgpu-sim/local_interconnect.cc301
-rw-r--r--src/gpgpu-sim/local_interconnect.h127
-rw-r--r--src/gpgpu-sim/mem_fetch.cc5
-rw-r--r--src/gpgpu-sim/mem_fetch.h1
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc13
-rw-r--r--src/gpgpu-sim/mem_latency_stat.h4
-rw-r--r--src/gpgpu-sim/scoreboard.cc4
-rw-r--r--src/gpgpu-sim/scoreboard.h4
-rw-r--r--src/gpgpu-sim/shader.cc175
-rw-r--r--src/gpgpu-sim/shader.h36
-rw-r--r--src/gpgpu-sim/shader_trace.h4
25 files changed, 961 insertions, 280 deletions
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc
index 8651869..ca88ec9 100644
--- a/src/gpgpu-sim/addrdec.cc
+++ b/src/gpgpu-sim/addrdec.cc
@@ -165,6 +165,27 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_
assert(tlx->chip < m_n_channel);
break;
}
+ case RANDOM:
+ {
+ new_addr_type chip_address = (addr>>ADDR_CHIP_S);
+ tr1_hash_map<new_addr_type,unsigned>::const_iterator got = address_random_interleaving.find (chip_address);
+ if ( got == address_random_interleaving.end() ) {
+ unsigned new_chip_id = rand() % (m_n_channel*m_n_sub_partition_in_channel);
+ address_random_interleaving[chip_address] = new_chip_id;
+ tlx->chip = new_chip_id/m_n_sub_partition_in_channel;
+ tlx->sub_partition = new_chip_id;
+ }
+ else {
+ unsigned new_chip_id = got->second;
+ tlx->chip = new_chip_id/m_n_sub_partition_in_channel;
+ tlx->sub_partition = new_chip_id;
+ }
+
+ assert(tlx->chip < m_n_channel);
+ assert(tlx->sub_partition < m_n_channel*m_n_sub_partition_in_channel);
+ return;
+ break;
+ }
case CUSTOM:
/* No custom set function implemented */
//Do you custom index here
@@ -175,9 +196,9 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_
}
// combine the chip address and the lower bits of DRAM bank address to form the subpartition ID
- unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1;
+ unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1;
tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel
- + (tlx->bk & sub_partition_addr_mask);
+ + (tlx->bk & sub_partition_addr_mask);
}
void linear_to_raw_address_translation::addrdec_parseoption(const char *option)
@@ -396,6 +417,10 @@ void linear_to_raw_address_translation::init(unsigned int n_channel, unsigned in
if (run_test) {
sweep_test();
}
+
+ if(memory_partition_indexing == RANDOM)
+ srand (1);
+
}
#include "../tr1_hash_map.h"
diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h
index bdc5fec..a5333fb 100644
--- a/src/gpgpu-sim/addrdec.h
+++ b/src/gpgpu-sim/addrdec.h
@@ -40,6 +40,7 @@ enum partition_index_function{
BITWISE_PERMUTATION,
IPOLY,
PAE,
+ RANDOM,
CUSTOM
};
@@ -55,6 +56,7 @@ struct addrdec_t {
unsigned sub_partition;
};
+
class linear_to_raw_address_translation {
public:
linear_to_raw_address_translation();
@@ -62,7 +64,7 @@ public:
void init(unsigned int n_channel, unsigned int n_sub_partition_in_channel);
// accessors
- void addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const;
+ void addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const;
new_addr_type partition_address( new_addr_type addr ) const;
private:
@@ -92,6 +94,7 @@ private:
unsigned int gap;
int m_n_channel;
int m_n_sub_partition_in_channel;
+
};
#endif
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index 6c11b43..5e36d4b 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -42,12 +42,13 @@ template class fifo_pipeline<mem_fetch>;
template class fifo_pipeline<dram_req_t>;
dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, memory_stats_t *stats,
- memory_partition_unit *mp )
+ memory_partition_unit *mp, gpgpu_sim* gpu )
{
id = partition_id;
m_memory_partition_unit = mp;
m_stats = stats;
m_config = config;
+ m_gpu = gpu;
//rowblp
access_num=0;
@@ -191,11 +192,12 @@ unsigned int dram_t::queue_limit() const
}
-dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy)
+dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu)
{
txbytes = 0;
dqbytes = 0;
data = mf;
+ m_gpu = gpu;
const addrdec_t &tlx = mf->get_tlx_addr();
@@ -226,9 +228,9 @@ dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_i
col = tlx.col;
nbytes = mf->get_data_size();
- timestamp = gpu_tot_sim_cycle + gpu_sim_cycle;
+ timestamp = m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle;
addr = mf->get_addr();
- insertion_time = (unsigned) gpu_sim_cycle;
+ insertion_time = (unsigned) m_gpu->gpu_sim_cycle;
rw = data->get_is_write()?WRITE:READ;
}
@@ -236,9 +238,9 @@ void dram_t::push( class mem_fetch *data )
{
assert(id == data->get_tlx_addr().chip); // Ensure request is in correct memory partition
- dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy);
+ dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy,m_memory_partition_unit->get_mgpu());
- data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
mrqq->push(mrq);
// stats...
@@ -259,7 +261,7 @@ void dram_t::scheduler_fifo()
if (!mrqq->empty()) {
unsigned int bkn;
dram_req_t *head_mrqq = mrqq->top();
- head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
bkn = head_mrqq->bk;
if (!bk[bkn]->mrq)
bk[bkn]->mrq = mrqq->pop();
@@ -283,7 +285,7 @@ void dram_t::cycle()
if (cmd->dqbytes >= cmd->nbytes) {
mem_fetch *data = cmd->data;
- data->set_status(IN_PARTITION_MC_RETURNQ,gpu_sim_cycle+gpu_tot_sim_cycle);
+ data->set_status(IN_PARTITION_MC_RETURNQ,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
if( data->get_access_type() != L1_WRBK_ACC && data->get_access_type() != L2_WRBK_ACC ) {
data->set_reply();
returnq->push(data);
@@ -566,7 +568,7 @@ bool dram_t::issue_col_command(int j)
bool issued = false;
unsigned grp = get_bankgrp_number(j);
if (bk[j]->mrq) { //if currently servicing a memory request
- bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
// correct row activated for a READ
if ( !issued && !CCDc && !bk[j]->RCDc &&
!(bkgrp[grp]->CCDLc) &&
@@ -654,7 +656,7 @@ bool dram_t::issue_row_command(int j)
bool issued = false;
unsigned grp = get_bankgrp_number(j);
if (bk[j]->mrq) { //if currently servicing a memory request
- bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
// bank is idle
//else
if ( !issued && !RRDc &&
@@ -723,10 +725,10 @@ void dram_t::print( FILE* simFile) const
id, m_config->nbk, m_config->busW, m_config->BL, m_config->CL );
fprintf(simFile,"tRRD=%d tCCD=%d, tRCD=%d tRAS=%d tRP=%d tRC=%d\n",
m_config->tRRD, m_config->tCCD, m_config->tRCD, m_config->tRAS, m_config->tRP, m_config->tRC );
- fprintf(simFile,"n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref_event=%d n_req=%d n_rd=%d n_rd_L2_A=%d n_write=%d n_wr_bk=%d bw_util=%.4g\n",
+ fprintf(simFile,"n_cmd=%llu n_nop=%llu n_act=%llu n_pre=%llu n_ref_event=%llu n_req=%llu n_rd=%llu n_rd_L2_A=%llu n_write=%llu n_wr_bk=%llu bw_util=%.4g\n",
n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_rd_L2_A, n_wr, n_wr_WB,
(float)bwutil/n_cmd);
- fprintf(simFile,"n_activity=%d dram_eff=%.4g\n",
+ fprintf(simFile,"n_activity=%llu dram_eff=%.4g\n",
n_activity, (float)bwutil/n_activity);
for (i=0;i<m_config->nbk;i++) {
fprintf(simFile, "bk%d: %da %di ",i,bk[i]->n_access,bk[i]->n_idle);
@@ -745,39 +747,39 @@ void dram_t::print( FILE* simFile) const
printf("\nBW Util details:\n");
printf("bwutil = %.6f \n", (float)bwutil/n_cmd);
- printf("total_CMD = %d \n", n_cmd);
- printf("util_bw = %d \n", util_bw);
- printf("Wasted_Col = %d \n", wasted_bw_col);
- printf("Wasted_Row = %d \n", wasted_bw_row);
- printf("Idle = %d \n", idle_bw);
+ printf("total_CMD = %llu \n", n_cmd);
+ printf("util_bw = %llu \n", util_bw);
+ printf("Wasted_Col = %llu \n", wasted_bw_col);
+ printf("Wasted_Row = %llu \n", wasted_bw_row);
+ printf("Idle = %llu \n", idle_bw);
printf("\nBW Util Bottlenecks: \n");
- printf("RCDc_limit = %d \n", RCDc_limit);
- printf("RCDWRc_limit = %d \n", RCDWRc_limit);
- printf("WTRc_limit = %d \n", WTRc_limit);
- printf("RTWc_limit = %d \n", RTWc_limit);
- printf("CCDLc_limit = %d \n", CCDLc_limit);
- printf("rwq = %d \n", rwq_limit);
- printf("CCDLc_limit_alone = %d \n", CCDLc_limit_alone);
- printf("WTRc_limit_alone = %d \n", WTRc_limit_alone);
- printf("RTWc_limit_alone = %d \n", RTWc_limit_alone);
+ printf("RCDc_limit = %llu \n", RCDc_limit);
+ printf("RCDWRc_limit = %llu \n", RCDWRc_limit);
+ printf("WTRc_limit = %llu \n", WTRc_limit);
+ printf("RTWc_limit = %llu \n", RTWc_limit);
+ printf("CCDLc_limit = %llu \n", CCDLc_limit);
+ printf("rwq = %llu \n", rwq_limit);
+ printf("CCDLc_limit_alone = %llu \n", CCDLc_limit_alone);
+ printf("WTRc_limit_alone = %llu \n", WTRc_limit_alone);
+ printf("RTWc_limit_alone = %llu \n", RTWc_limit_alone);
printf("\nCommands details: \n");
- printf("total_CMD = %d \n", n_cmd);
- printf("n_nop = %d \n", n_nop);
- printf("Read = %d \n", n_rd);
- printf("Write = %d \n",n_wr);
- printf("L2_Alloc = %d \n", n_rd_L2_A);
- printf("L2_WB = %d \n", n_wr_WB);
- printf("n_act = %d \n", n_act);
- printf("n_pre = %d \n", n_pre);
- printf("n_ref = %d \n", n_ref);
- printf("n_req = %d \n", n_req );
- printf("total_req = %d \n", n_rd+n_wr+n_rd_L2_A+n_wr_WB);
+ printf("total_CMD = %llu \n", n_cmd);
+ printf("n_nop = %llu \n", n_nop);
+ printf("Read = %llu \n", n_rd);
+ printf("Write = %llu \n",n_wr);
+ printf("L2_Alloc = %llu \n", n_rd_L2_A);
+ printf("L2_WB = %llu \n", n_wr_WB);
+ printf("n_act = %llu \n", n_act);
+ printf("n_pre = %llu \n", n_pre);
+ printf("n_ref = %llu \n", n_ref);
+ printf("n_req = %llu \n", n_req );
+ printf("total_req = %llu \n", n_rd+n_wr+n_rd_L2_A+n_wr_WB);
printf("\nDual Bus Interface Util: \n");
- printf("issued_total_row = %lu \n", issued_total_row);
- printf("issued_total_col = %lu \n", issued_total_col);
+ printf("issued_total_row = %llu \n", issued_total_row);
+ printf("issued_total_col = %llu \n", issued_total_col);
printf("Row_Bus_Util = %.6f \n", (float)issued_total_row / n_cmd);
printf("CoL_Bus_Util = %.6f \n", (float)issued_total_col / n_cmd);
printf("Either_Row_CoL_Bus_Util = %.6f \n", (float)issued_total / n_cmd);
@@ -815,7 +817,7 @@ void dram_t::visualize() const
void dram_t::print_stat( FILE* simFile )
{
- fprintf(simFile,"DRAM (%d): n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref=%d n_req=%d n_rd=%d n_write=%d bw_util=%.4g ",
+ fprintf(simFile,"DRAM (%llu): n_cmd=%llu n_nop=%llu n_act=%llu n_pre=%llu n_ref=%llu n_req=%llu n_rd=%llu n_write=%llu bw_util=%.4g ",
id, n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_wr,
(float)bwutil/n_cmd);
fprintf(simFile, "mrqq: %d %.4g mrqsmax=%d ", max_mrqs, (float)ave_mrqs/n_cmd, max_mrqs_temp);
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index bee5b7b..7a3a2da 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -48,7 +48,7 @@
class dram_req_t {
public:
- dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy);
+ dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu);
unsigned int row;
unsigned int col;
@@ -62,6 +62,7 @@ public:
unsigned long long int addr;
unsigned int insertion_time;
class mem_fetch * data;
+ class gpgpu_sim * m_gpu;
};
struct bankgrp_t
@@ -110,7 +111,7 @@ class dram_t
{
public:
dram_t( unsigned int parition_id, const struct memory_config *config, class memory_stats_t *stats,
- class memory_partition_unit *mp );
+ class memory_partition_unit *mp, class gpgpu_sim* gpu );
bool full(bool is_write) const;
void print( FILE* simFile ) const;
@@ -129,6 +130,7 @@ public:
void dram_log (int task);
class memory_partition_unit *m_memory_partition_unit;
+ class gpgpu_sim* m_gpu;
unsigned int id;
// Power Model
@@ -178,39 +180,39 @@ private:
unsigned int dram_eff_bins[10];
unsigned int last_n_cmd, last_n_activity, last_bwutil;
- unsigned int n_cmd;
- unsigned int n_activity;
- unsigned int n_nop;
- unsigned int n_act;
- unsigned int n_pre;
- unsigned int n_ref;
- unsigned int n_rd;
- unsigned int n_rd_L2_A;
- unsigned int n_wr;
- unsigned int n_wr_WB;
- unsigned int n_req;
- unsigned int max_mrqs_temp;
+ unsigned long long n_cmd;
+ unsigned long long n_activity;
+ unsigned long long n_nop;
+ unsigned long long n_act;
+ unsigned long long n_pre;
+ unsigned long long n_ref;
+ unsigned long long n_rd;
+ unsigned long long n_rd_L2_A;
+ unsigned long long n_wr;
+ unsigned long long n_wr_WB;
+ unsigned long long n_req;
+ unsigned long long max_mrqs_temp;
- //some statistics to collect to see where BW is wasted?
- unsigned wasted_bw_row;
- unsigned wasted_bw_col;
- unsigned util_bw;
- unsigned idle_bw;
- unsigned RCDc_limit;
- unsigned CCDLc_limit;
- unsigned CCDLc_limit_alone;
- unsigned CCDc_limit;
- unsigned WTRc_limit;
- unsigned WTRc_limit_alone;
- unsigned RCDWRc_limit;
- unsigned RTWc_limit;
- unsigned RTWc_limit_alone;
- unsigned rwq_limit;
+ //some statistics to see where BW is wasted?
+ unsigned long long wasted_bw_row;
+ unsigned long long wasted_bw_col;
+ unsigned long long util_bw;
+ unsigned long long idle_bw;
+ unsigned long long RCDc_limit;
+ unsigned long long CCDLc_limit;
+ unsigned long long CCDLc_limit_alone;
+ unsigned long long CCDc_limit;
+ unsigned long long WTRc_limit;
+ unsigned long long WTRc_limit_alone;
+ unsigned long long RCDWRc_limit;
+ unsigned long long RTWc_limit;
+ unsigned long long RTWc_limit_alone;
+ unsigned long long rwq_limit;
//row locality, BLP and other statistics
- unsigned long access_num;
- unsigned long read_num;
- unsigned long write_num;
+ unsigned long long access_num;
+ unsigned long long read_num;
+ unsigned long long write_num;
unsigned long long hits_num;
unsigned long long hits_read_num;
unsigned long long hits_write_num;
diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc
index ff50050..6ee6271 100644
--- a/src/gpgpu-sim/dram_sched.cc
+++ b/src/gpgpu-sim/dram_sched.cc
@@ -84,13 +84,13 @@ void frfcfs_scheduler::add_req( dram_req_t *req )
void frfcfs_scheduler::data_collection(unsigned int bank)
{
- if (gpu_sim_cycle > row_service_timestamp[bank]) {
- curr_row_service_time[bank] = gpu_sim_cycle - row_service_timestamp[bank];
+ if (m_dram->m_gpu->gpu_sim_cycle > row_service_timestamp[bank]) {
+ curr_row_service_time[bank] = m_dram->m_gpu->gpu_sim_cycle - row_service_timestamp[bank];
if (curr_row_service_time[bank] > m_stats->max_servicetime2samerow[m_dram->id][bank])
m_stats->max_servicetime2samerow[m_dram->id][bank] = curr_row_service_time[bank];
}
curr_row_service_time[bank] = 0;
- row_service_timestamp[bank] = gpu_sim_cycle;
+ row_service_timestamp[bank] = m_dram->m_gpu->gpu_sim_cycle;
if (m_stats->concurrent_row_access[m_dram->id][bank] > m_stats->max_conc_access2samerow[m_dram->id][bank]) {
m_stats->max_conc_access2samerow[m_dram->id][bank] = m_stats->concurrent_row_access[m_dram->id][bank];
}
@@ -215,7 +215,7 @@ void dram_t::scheduler_frfcfs()
m_stats->total_n_reads++;
}
- req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
sched->add_req(req);
}
@@ -228,14 +228,14 @@ void dram_t::scheduler_frfcfs()
req = sched->schedule(b, bk[b]->curr_row);
if ( req ) {
- req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
prio = (prio+1)%m_config->nbk;
bk[b]->mrq = req;
if (m_config->gpgpu_memlatency_stat) {
- mrq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - bk[b]->mrq->timestamp;
+ mrq_latency = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle - bk[b]->mrq->timestamp;
m_stats->tot_mrq_latency += mrq_latency;
m_stats->tot_mrq_num++;
- bk[b]->mrq->timestamp = gpu_tot_sim_cycle + gpu_sim_cycle;
+ bk[b]->mrq->timestamp =m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle;
m_stats->mrq_lat_table[LOGB2(mrq_latency)]++;
if (mrq_latency > m_stats->max_mrq_latency) {
m_stats->max_mrq_latency = mrq_latency;
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index ba81440..62849f8 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gpu-cache.h"
+#include "gpu-sim.h"
#include "stat-tool.h"
#include <assert.h>
@@ -256,7 +257,7 @@ enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, m
unsigned invalid_line = (unsigned)-1;
unsigned valid_line = (unsigned)-1;
- unsigned valid_timestamp = (unsigned)-1;
+ unsigned long long valid_timestamp = (unsigned)-1;
bool all_reserved = true;
@@ -654,7 +655,7 @@ enum cache_request_status cache_stats::select_stats_status(enum cache_request_st
return access;
}
-unsigned &cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome){
+unsigned long long &cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome){
///
/// Simple method to read/modify the stat corresponding to (access_type, access_outcome)
/// Used overloaded () to avoid the need for separate read/write member functions
@@ -673,7 +674,7 @@ unsigned &cache_stats::operator()(int access_type, int access_outcome, bool fail
}
}
-unsigned cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome) const{
+unsigned long long cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome) const{
///
/// Const accessor into m_stats.
///
@@ -740,7 +741,7 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const{
std::string m_cache_name = cache_name;
for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- fprintf(fout, "\t%s[%s][%s] = %u\n",
+ fprintf(fout, "\t%s[%s][%s] = %llu\n",
m_cache_name.c_str(),
mem_access_type_str((enum mem_access_type)type),
cache_request_status_str((enum cache_request_status)status),
@@ -751,7 +752,7 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const{
}
for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
if(total_access[type] > 0)
- fprintf(fout, "\t%s[%s][%s] = %u\n",
+ fprintf(fout, "\t%s[%s][%s] = %llu\n",
m_cache_name.c_str(),
mem_access_type_str((enum mem_access_type)type),
"TOTAL_ACCESS",
@@ -788,13 +789,13 @@ void cache_sub_stats::print_port_stats(FILE *fout, const char *cache_name) const
fprintf(fout, "%s_fill_port_util = %.3f\n", cache_name, fill_port_util);
}
-unsigned cache_stats::get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{
+unsigned long long cache_stats::get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{
///
/// Returns a sum of the stats corresponding to each "access_type" and "access_status" pair.
/// "access_type" is an array of "num_access_type" mem_access_types.
/// "access_status" is an array of "num_access_status" cache_request_statuses.
///
- unsigned total=0;
+ unsigned long long total=0;
for(unsigned type =0; type < num_access_type; ++type){
for(unsigned status=0; status < num_access_status; ++status){
if(!check_valid((int)access_type[type], (int)access_status[status]))
@@ -1183,7 +1184,8 @@ data_cache::wr_miss_wa_naive( new_addr_type addr,
mf->get_wid(),
mf->get_sid(),
mf->get_tpc(),
- mf->get_mem_config());
+ mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
bool do_miss = false;
bool wb = false;
@@ -1201,7 +1203,7 @@ data_cache::wr_miss_wa_naive( new_addr_type addr,
if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) {
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_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1245,7 +1247,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
// (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_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1297,6 +1299,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
mf->get_sid(),
mf->get_tpc(),
mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle,
NULL,
mf);
@@ -1320,7 +1323,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
// (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_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1373,7 +1376,7 @@ data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr,
// (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_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1458,7 +1461,7 @@ data_cache::rd_miss_base( new_addr_type addr,
// (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_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events);
}
return MISS;
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index e663cf6..85e534e 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -119,9 +119,9 @@ struct cache_block_t {
virtual enum cache_block_state get_status( 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 unsigned get_last_access_time() = 0;
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask) = 0;
- virtual unsigned get_alloc_time() = 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;
+ virtual unsigned long long get_alloc_time() = 0;
virtual void set_ignore_on_fill(bool m_ignore, mem_access_sector_mask_t sector_mask) = 0;
virtual void set_modified_on_fill(bool m_modified, mem_access_sector_mask_t sector_mask) = 0;
virtual unsigned get_modified_size() = 0;
@@ -192,15 +192,15 @@ struct line_cache_block: public cache_block_t {
{
m_status = status;
}
- virtual unsigned get_last_access_time()
+ virtual unsigned long long get_last_access_time()
{
return m_last_access_time;
}
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask)
+ virtual void set_last_access_time(unsigned long long time, mem_access_sector_mask_t sector_mask)
{
m_last_access_time = time;
}
- virtual unsigned get_alloc_time()
+ virtual unsigned long long get_alloc_time()
{
return m_alloc_time;
}
@@ -229,9 +229,9 @@ struct line_cache_block: public cache_block_t {
private:
- unsigned m_alloc_time;
- unsigned m_last_access_time;
- unsigned m_fill_time;
+ unsigned long long m_alloc_time;
+ unsigned long long m_last_access_time;
+ unsigned long long m_fill_time;
cache_block_state m_status;
bool m_ignore_on_fill_status;
bool m_set_modified_on_fill;
@@ -364,12 +364,12 @@ struct sector_cache_block : public cache_block_t {
m_status[sidx] = status;
}
- virtual unsigned get_last_access_time()
+ virtual unsigned long long get_last_access_time()
{
return m_line_last_access_time;
}
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask)
+ virtual void set_last_access_time(unsigned long long time, mem_access_sector_mask_t sector_mask)
{
unsigned sidx = get_sector_index(sector_mask);
@@ -377,7 +377,7 @@ struct sector_cache_block : public cache_block_t {
m_line_last_access_time = time;
}
- virtual unsigned get_alloc_time()
+ virtual unsigned long long get_alloc_time()
{
return m_line_alloc_time;
}
@@ -915,10 +915,10 @@ private:
/// Simple struct to maintain cache accesses, misses, pending hits, and reservation fails.
///
struct cache_sub_stats{
- unsigned accesses;
- unsigned misses;
- unsigned pending_hits;
- unsigned res_fails;
+ unsigned long long accesses;
+ unsigned long long misses;
+ unsigned long long pending_hits;
+ unsigned long long res_fails;
unsigned long long port_available_cycles;
unsigned long long data_port_busy_cycles;
@@ -981,14 +981,14 @@ public:
void inc_stats(int access_type, int access_outcome);
void inc_fail_stats(int access_type, int fail_outcome);
enum cache_request_status select_stats_status(enum cache_request_status probe, enum cache_request_status access) const;
- unsigned &operator()(int access_type, int access_outcome, bool fail_outcome);
- unsigned operator()(int access_type, int access_outcome, bool fail_outcome) const;
+ unsigned long long &operator()(int access_type, int access_outcome, bool fail_outcome);
+ unsigned long long operator()(int access_type, int access_outcome, bool fail_outcome) const;
cache_stats operator+(const cache_stats &cs);
cache_stats &operator+=(const cache_stats &cs);
void print_stats(FILE *fout, const char *cache_name = "Cache_stats") const;
void print_fail_stats(FILE *fout, const char *cache_name = "Cache_fail_stats") const;
- unsigned get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
+ unsigned long long get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
void get_sub_stats(struct cache_sub_stats &css) const;
void sample_cache_port_utility(bool data_port_busy, bool fill_port_busy);
@@ -996,8 +996,8 @@ private:
bool check_valid(int type, int status) const;
bool check_fail_valid(int type, int fail) const;
- std::vector< std::vector<unsigned> > m_stats;
- std::vector< std::vector<unsigned> > m_fail_stats;
+ std::vector< std::vector<unsigned long long> > m_stats;
+ std::vector< std::vector<unsigned long long> > m_fail_stats;
unsigned long long m_cache_port_available_cycles;
unsigned long long m_cache_data_port_busy_cycles;
@@ -1212,12 +1212,13 @@ public:
data_cache( const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
mem_fetch_allocator *mfcreator, enum mem_fetch_status status,
- mem_access_type wr_alloc_type, mem_access_type wrbk_type )
+ mem_access_type wr_alloc_type, mem_access_type wrbk_type, class gpgpu_sim* gpu )
: baseline_cache(name,config,core_id,type_id,memport,status)
{
init( mfcreator );
m_wr_alloc_type = wr_alloc_type;
m_wrbk_type = wrbk_type;
+ m_gpu=gpu;
}
virtual ~data_cache() {}
@@ -1275,16 +1276,19 @@ protected:
enum mem_fetch_status status,
tag_array* new_tag_array,
mem_access_type wr_alloc_type,
- mem_access_type wrbk_type)
+ mem_access_type wrbk_type,
+ class gpgpu_sim* gpu )
: baseline_cache(name, config, core_id, type_id, memport,status, new_tag_array)
{
init( mfcreator );
m_wr_alloc_type = wr_alloc_type;
m_wrbk_type = wrbk_type;
+ m_gpu=gpu;
}
mem_access_type m_wr_alloc_type; // Specifies type of write allocate request (e.g., L1 or L2)
mem_access_type m_wrbk_type; // Specifies type of writeback request (e.g., L1 or L2)
+ class gpgpu_sim* m_gpu;
//! A general function that takes the result of a tag_array probe
// and performs the correspding functions based on the cache configuration
@@ -1441,8 +1445,8 @@ class l1_cache : public data_cache {
public:
l1_cache(const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
- mem_fetch_allocator *mfcreator, enum mem_fetch_status status )
- : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC){}
+ mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu )
+ : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu){}
virtual ~l1_cache(){}
@@ -1460,10 +1464,11 @@ protected:
mem_fetch_interface *memport,
mem_fetch_allocator *mfcreator,
enum mem_fetch_status status,
- tag_array* new_tag_array )
+ tag_array* new_tag_array,
+ class gpgpu_sim* gpu)
: data_cache( name,
config,
- core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC ){}
+ core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu ){}
};
@@ -1473,8 +1478,8 @@ class l2_cache : public data_cache {
public:
l2_cache(const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
- mem_fetch_allocator *mfcreator, enum mem_fetch_status status )
- : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC){}
+ mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu )
+ : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC, gpu){}
virtual ~l2_cache() {}
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index ec570bf..6f19640 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -82,22 +82,7 @@ class gpgpu_sim_wrapper {};
bool g_interactive_debugger_enabled=false;
-
-unsigned long long gpu_sim_cycle = 0;
-unsigned long long gpu_tot_sim_cycle = 0;
-
-
-// performance counter for stalls due to congestion.
-unsigned int gpu_stall_dramfull = 0;
-unsigned int gpu_stall_icnt2sh = 0;
-unsigned long long partiton_reqs_in_parallel = 0;
-unsigned long long partiton_reqs_in_parallel_total = 0;
-unsigned long long partiton_reqs_in_parallel_util = 0;
-unsigned long long partiton_reqs_in_parallel_util_total = 0;
-unsigned long long gpu_sim_cycle_parition_util = 0;
-unsigned long long gpu_tot_sim_cycle_parition_util = 0;
-unsigned long long partiton_replys_in_parallel = 0;
-unsigned long long partiton_replys_in_parallel_total = 0;
+tr1_hash_map<new_addr_type,unsigned> address_random_interleaving;
/* Clock Domains */
@@ -110,8 +95,6 @@ unsigned long long partiton_replys_in_parallel_total = 0;
#define MEM_LATENCY_STAT_IMPL
-
-
#include "mem_latency_stat.h"
void power_config::reg_options(class OptionParser * opp)
@@ -315,8 +298,8 @@ 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, "-adpative_volta_cache_config", OPT_BOOL, &adpative_volta_cache_config,
- "adpative_volta_cache_config",
+ option_parser_register(opp, "-adaptive_volta_cache_config", OPT_BOOL, &adaptive_volta_cache_config,
+ "adaptive_volta_cache_config",
"0");
option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_sizeDefault,
"Size of shared memory per shader core (default 16kB)",
@@ -476,6 +459,7 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm,
"Support concurrent kernels on a SM (default = disabled)",
"0");
+
}
void gpgpu_sim_config::reg_options(option_parser_t opp)
@@ -499,6 +483,12 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-liveness_message_freq", OPT_INT64, &liveness_message_freq,
"Minimum number of seconds between simulation liveness messages (0 = always print)",
"1");
+ option_parser_register(opp, "-gpgpu_compute_capability_major", OPT_UINT32, &gpgpu_compute_capability_major,
+ "Major compute capability version number",
+ "7");
+ option_parser_register(opp, "-gpgpu_compute_capability_minor", OPT_UINT32, &gpgpu_compute_capability_minor,
+ "Minor compute capability version number",
+ "0");
option_parser_register(opp, "-gpgpu_flush_l1_cache", OPT_BOOL, &gpgpu_flush_l1_cache,
"Flush L1 cache at the end of each kernel call",
"0");
@@ -532,6 +522,14 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-visualizer_zlevel", OPT_INT32,
&g_visualizer_zlevel, "Compression level of the visualizer output log (0=no comp, 9=highest)",
"6");
+ option_parser_register(opp, "-gpgpu_stack_size_limit", OPT_INT32, &stack_size_limit,
+ "GPU thread stack size", "1024" );
+ option_parser_register(opp, "-gpgpu_heap_size_limit", OPT_INT32, &heap_size_limit,
+ "GPU malloc heap size ", "8388608" );
+ option_parser_register(opp, "-gpgpu_runtime_sync_depth_limit", OPT_INT32, &runtime_sync_depth_limit,
+ "GPU device runtime synchronize depth", "2" );
+ option_parser_register(opp, "-gpgpu_runtime_pending_launch_count_limit", OPT_INT32, &runtime_pending_launch_count_limit,
+ "GPU device runtime pending launch count", "2048" );
option_parser_register(opp, "-trace_enabled", OPT_BOOL,
&Trace::enabled, "Turn on traces",
"0");
@@ -714,7 +712,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
#endif
m_shader_stats = new shader_core_stats(m_shader_config);
- m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config);
+ m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config,this);
average_pipeline_duty_cycle = (float *)malloc(sizeof(float));
active_sms=(float *)malloc(sizeof(float));
m_power_stats = new power_stat_t(m_shader_config,average_pipeline_duty_cycle,active_sms,m_shader_stats,m_memory_config,m_memory_stats);
@@ -725,6 +723,16 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
m_total_cta_launched = 0;
gpu_deadlock = false;
+ gpu_stall_dramfull = 0;
+ gpu_stall_icnt2sh = 0;
+ partiton_reqs_in_parallel = 0;
+ partiton_reqs_in_parallel_total = 0;
+ partiton_reqs_in_parallel_util = 0;
+ partiton_reqs_in_parallel_util_total = 0;
+ gpu_sim_cycle_parition_util = 0;
+ gpu_tot_sim_cycle_parition_util = 0;
+ partiton_replys_in_parallel = 0;
+ partiton_replys_in_parallel_total = 0;
m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters];
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
@@ -733,7 +741,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem];
m_memory_sub_partition = new memory_sub_partition*[m_memory_config->m_n_mem_sub_partition];
for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
- m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats);
+ m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats, this);
for (unsigned p = 0; p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) {
unsigned submpid = i * m_memory_config->m_n_sub_partition_per_memory_channel + p;
m_memory_sub_partition[submpid] = m_memory_partition_unit[i]->get_sub_partition(p);
@@ -794,6 +802,16 @@ void gpgpu_sim::set_prop( cudaDeviceProp *prop )
m_cuda_properties = prop;
}
+int gpgpu_sim::compute_capability_major() const
+{
+ return m_config.gpgpu_compute_capability_major;
+}
+
+int gpgpu_sim::compute_capability_minor() const
+{
+ return m_config.gpgpu_compute_capability_minor;
+}
+
const struct cudaDeviceProp *gpgpu_sim::get_prop() const
{
return m_cuda_properties;
@@ -1157,19 +1175,19 @@ void gpgpu_sim::gpu_print_stat()
m_memory_sub_partition[i]->accumulate_L2cache_stats(l2_stats);
m_memory_sub_partition[i]->get_L2cache_sub_stats(l2_css);
- fprintf( stdout, "L2_cache_bank[%d]: Access = %u, Miss = %u, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
+ fprintf( stdout, "L2_cache_bank[%d]: Access = %llu, Miss = %llu, Miss_rate = %.3lf, Pending_hits = %llu, Reservation_fails = %llu\n",
i, l2_css.accesses, l2_css.misses, (double)l2_css.misses / (double)l2_css.accesses, l2_css.pending_hits, l2_css.res_fails);
total_l2_css += l2_css;
}
if (!m_memory_config->m_L2_config.disabled() && m_memory_config->m_L2_config.get_num_lines()) {
//L2c_print_cache_stat();
- printf("L2_total_cache_accesses = %u\n", total_l2_css.accesses);
- printf("L2_total_cache_misses = %u\n", total_l2_css.misses);
+ printf("L2_total_cache_accesses = %llu\n", total_l2_css.accesses);
+ printf("L2_total_cache_misses = %llu\n", total_l2_css.misses);
if(total_l2_css.accesses > 0)
printf("L2_total_cache_miss_rate = %.4lf\n", (double)total_l2_css.misses/(double)total_l2_css.accesses);
- printf("L2_total_cache_pending_hits = %u\n", total_l2_css.pending_hits);
- printf("L2_total_cache_reservation_fails = %u\n", total_l2_css.res_fails);
+ printf("L2_total_cache_pending_hits = %llu\n", total_l2_css.pending_hits);
+ printf("L2_total_cache_reservation_fails = %llu\n", total_l2_css.res_fails);
printf("L2_total_cache_breakdown:\n");
l2_stats.print_stats(stdout, "L2_cache_stats_breakdown");
printf("L2_total_cache_reservation_fail_breakdown:\n");
@@ -1477,7 +1495,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
shader_CTA_count_log(m_sid, 1);
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: cta:%2u, start_tid:%4u, end_tid:%4u, initialized @(%lld,%lld)\n",
- free_cta_hw_id, start_thread, end_thread, gpu_sim_cycle, gpu_tot_sim_cycle );
+ free_cta_hw_id, start_thread, end_thread, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle );
}
@@ -1694,7 +1712,7 @@ void gpgpu_sim::cycle()
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
m_cluster[i]->get_current_occupancy(active, total);
}
- DPRINTF(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
+ DPRINTFG(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
gpu_tot_sim_insn + gpu_sim_insn,
(double)gpu_sim_insn/(double)gpu_sim_cycle,
float(active)/float(total) * 100, active, total,
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 6ce5524..5ea5765 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -62,9 +62,7 @@
#define SAMPLELOG 222
#define DUMPLOG 333
-
-
-
+extern tr1_hash_map<new_addr_type,unsigned> address_random_interleaving;
enum dram_ctrl_t {
DRAM_FIFO=0,
@@ -293,9 +291,6 @@ struct memory_config {
bool m_perf_sim_memcpy;
};
-// global counters and flags (please try not to add to this list!!!)
-extern unsigned long long gpu_sim_cycle;
-extern unsigned long long gpu_tot_sim_cycle;
extern bool g_interactive_debugger_enabled;
class gpgpu_sim_config : public power_config, public gpgpu_functional_sim_config {
@@ -337,6 +332,11 @@ public:
unsigned get_max_concurrent_kernel() const { return max_concurrent_kernel; }
unsigned checkpoint_option;
+ size_t stack_limit() const {return stack_size_limit; }
+ size_t heap_limit() const {return heap_size_limit; }
+ size_t sync_depth_limit() const {return runtime_sync_depth_limit; }
+ size_t pending_launch_count_limit() const {return runtime_pending_launch_count_limit;}
+
private:
void init_clock_domains(void );
@@ -377,8 +377,15 @@ private:
int gpu_stat_sample_freq;
int gpu_runtime_stat_flag;
+ // Device Limits
+ size_t stack_size_limit;
+ size_t heap_size_limit;
+ size_t runtime_sync_depth_limit;
+ size_t runtime_pending_launch_count_limit;
-
+ //gpu compute capability options
+ unsigned int gpgpu_compute_capability_major;
+ unsigned int gpgpu_compute_capability_minor;
unsigned long long liveness_message_freq;
friend class gpgpu_sim;
@@ -438,6 +445,8 @@ public:
int shared_mem_size() const;
int shared_mem_per_block() const;
+ int compute_capability_major() const;
+ int compute_capability_minor() const;
int num_registers_per_core() const;
int num_registers_per_block() const;
int wrp_size() const;
@@ -553,6 +562,18 @@ public:
occupancy_stats gpu_occupancy;
occupancy_stats gpu_tot_occupancy;
+ // performance counter for stalls due to congestion.
+ unsigned int gpu_stall_dramfull;
+ unsigned int gpu_stall_icnt2sh;
+ unsigned long long partiton_reqs_in_parallel;
+ unsigned long long partiton_reqs_in_parallel_total;
+ unsigned long long partiton_reqs_in_parallel_util;
+ unsigned long long partiton_reqs_in_parallel_util_total;
+ unsigned long long gpu_sim_cycle_parition_util;
+ unsigned long long gpu_tot_sim_cycle_parition_util;
+ unsigned long long partiton_replys_in_parallel;
+ unsigned long long partiton_replys_in_parallel_total;
+
FuncCache get_cache_config(std::string kernel_name);
void set_cache_config(std::string kernel_name, FuncCache cacheConfig );
diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc
index ee58ece..6e0950c 100644
--- a/src/gpgpu-sim/icnt_wrapper.cc
+++ b/src/gpgpu-sim/icnt_wrapper.cc
@@ -29,6 +29,8 @@
#include <assert.h>
#include "../intersim2/globals.hpp"
#include "../intersim2/interconnect_interface.hpp"
+#include "local_interconnect.h"
+
icnt_create_p icnt_create;
icnt_init_p icnt_init;
@@ -42,9 +44,13 @@ icnt_display_overall_stats_p icnt_display_overall_stats;
icnt_display_state_p icnt_display_state;
icnt_get_flit_size_p icnt_get_flit_size;
-int g_network_mode;
+unsigned g_network_mode;
char* g_network_config_filename;
+
+struct inct_config g_inct_config;
+LocalInterconnect *g_localicnt_interface;
+
#include "../option_parser.h"
// Wrapper to intersim2 to accompany old icnt_wrapper
@@ -105,10 +111,78 @@ static unsigned intersim2_get_flit_size()
return g_icnt_interface->GetFlitSize();
}
+
+//////////////////////////////////////////////////////
+
+static void LocalInterconnect_create(unsigned int n_shader, unsigned int n_mem)
+{
+ g_localicnt_interface->CreateInterconnect(n_shader, n_mem);
+}
+
+static void LocalInterconnect_init()
+{
+ g_localicnt_interface->Init();
+}
+
+static bool LocalInterconnect_has_buffer(unsigned input, unsigned int size)
+{
+ return g_localicnt_interface->HasBuffer(input, size);
+}
+
+static void LocalInterconnect_push(unsigned input, unsigned output, void* data, unsigned int size)
+{
+ g_localicnt_interface->Push(input, output, data, size);
+}
+
+static void* LocalInterconnect_pop(unsigned output)
+{
+ return g_localicnt_interface->Pop(output);
+}
+
+static void LocalInterconnect_transfer()
+{
+ g_localicnt_interface->Advance();
+}
+
+static bool LocalInterconnect_busy()
+{
+ return g_localicnt_interface->Busy();
+}
+
+static void LocalInterconnect_display_stats()
+{
+ g_localicnt_interface->DisplayStats();
+}
+
+static void LocalInterconnect_display_overall_stats()
+{
+ g_localicnt_interface->DisplayOverallStats();
+}
+
+static void LocalInterconnect_display_state(FILE *fp)
+{
+ g_localicnt_interface->DisplayState(fp);
+}
+
+static unsigned LocalInterconnect_get_flit_size()
+{
+ return g_localicnt_interface->GetFlitSize();
+}
+
+
+///////////////////////////
+
void icnt_reg_options( class OptionParser * opp )
{
option_parser_register(opp, "-network_mode", OPT_INT32, &g_network_mode, "Interconnection network mode", "1");
option_parser_register(opp, "-inter_config_file", OPT_CSTR, &g_network_config_filename, "Interconnection network config file", "mesh");
+
+
+ //parameters for local xbar
+ option_parser_register(opp, "-inct_in_buffer_limit", OPT_UINT32, &g_inct_config.in_buffer_limit, "in_buffer_limit", "64");
+ option_parser_register(opp, "-inct_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64");
+ option_parser_register(opp, "-inct_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2");
+
}
void icnt_wrapper_init()
@@ -129,6 +203,20 @@ void icnt_wrapper_init()
icnt_display_state = intersim2_display_state;
icnt_get_flit_size = intersim2_get_flit_size;
break;
+ case LOCAL_XBAR:
+ g_localicnt_interface = LocalInterconnect::New(g_inct_config);
+ icnt_create = LocalInterconnect_create;
+ icnt_init = LocalInterconnect_init;
+ icnt_has_buffer = LocalInterconnect_has_buffer;
+ icnt_push = LocalInterconnect_push;
+ icnt_pop = LocalInterconnect_pop;
+ icnt_transfer = LocalInterconnect_transfer;
+ icnt_busy = LocalInterconnect_busy;
+ icnt_display_stats = LocalInterconnect_display_stats;
+ icnt_display_overall_stats = LocalInterconnect_display_overall_stats;
+ icnt_display_state = LocalInterconnect_display_state;
+ icnt_get_flit_size = LocalInterconnect_get_flit_size;
+ break;
default:
assert(0);
break;
diff --git a/src/gpgpu-sim/icnt_wrapper.h b/src/gpgpu-sim/icnt_wrapper.h
index a4d123e..e1086f9 100644
--- a/src/gpgpu-sim/icnt_wrapper.h
+++ b/src/gpgpu-sim/icnt_wrapper.h
@@ -57,13 +57,16 @@ extern icnt_display_stats_p icnt_display_stats;
extern icnt_display_overall_stats_p icnt_display_overall_stats;
extern icnt_display_state_p icnt_display_state;
extern icnt_get_flit_size_p icnt_get_flit_size;
-extern int g_network_mode;
+extern unsigned g_network_mode;
enum network_mode {
INTERSIM = 1,
+ LOCAL_XBAR = 2,
N_NETWORK_MODE
};
+
+
void icnt_wrapper_init();
void icnt_reg_options( class OptionParser * opp );
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 25da107..526e999 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -46,7 +46,7 @@
#include "l2cache_trace.h"
-mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const
+mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const
{
assert( wr );
mem_access_t access( type, addr, size, wr );
@@ -56,22 +56,25 @@ mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type ty
-1,
-1,
-1,
- m_memory_config );
+ m_memory_config,
+ cycle);
return mf;
}
memory_partition_unit::memory_partition_unit( unsigned partition_id,
const struct memory_config *config,
- class memory_stats_t *stats )
-: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config)
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
+: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config), m_gpu(gpu)
{
- m_dram = new dram_t(m_id,m_config,m_stats,this);
+ m_dram = new dram_t(m_id,m_config,m_stats,this,gpu);
m_sub_partition = new memory_sub_partition*[m_config->m_n_sub_partition_per_memory_channel];
for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
unsigned sub_partition_id = m_id * m_config->m_n_sub_partition_per_memory_channel + p;
- m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats);
+ m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats, gpu);
}
+
}
void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask )
@@ -80,7 +83,7 @@ void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_s
std::string mystring =
mask.to_string<char,std::string::traits_type,std::string::allocator_type>();
MEMPART_DPRINTF("Copy Engine Request Received For Address=%llx, local_subpart=%u, global_subpart=%u, sector_mask=%s \n", addr, p, global_subpart_id, mystring.c_str());
- m_sub_partition[p]->force_l2_tag_update(addr,gpu_sim_cycle+gpu_tot_sim_cycle, mask);
+ m_sub_partition[p]->force_l2_tag_update(addr,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle, mask);
}
memory_partition_unit::~memory_partition_unit()
@@ -218,7 +221,7 @@ void memory_partition_unit::dram_cycle()
delete mf_return;
} else {
m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
- mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_arbitration_metadata.return_credit(dest_spid);
MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid);
}
@@ -247,9 +250,9 @@ void memory_partition_unit::dram_cycle()
MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid);
dram_delay_t d;
d.req = mf;
- d.ready_cycle = gpu_sim_cycle+gpu_tot_sim_cycle + m_config->dram_latency;
+ d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency;
m_dram_latency_queue.push_back(d);
- mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_arbitration_metadata.borrow_credit(spid);
break; // the DRAM should only accept one request per cycle
}
@@ -258,7 +261,7 @@ void memory_partition_unit::dram_cycle()
// DRAM latency queue
- if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) {
+ if( !m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) {
mem_fetch* mf = m_dram_latency_queue.front().req;
m_dram_latency_queue.pop_front();
m_dram->push(mf);
@@ -310,11 +313,13 @@ void memory_partition_unit::print( FILE *fp ) const
memory_sub_partition::memory_sub_partition( unsigned sub_partition_id,
const struct memory_config *config,
- class memory_stats_t *stats )
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
{
m_id = sub_partition_id;
m_config=config;
m_stats=stats;
+ m_gpu = gpu;
m_memcpy_cycle_offset = 0;
assert(m_id < m_config->m_n_mem_sub_partition);
@@ -325,7 +330,7 @@ memory_sub_partition::memory_sub_partition( unsigned sub_partition_id,
m_mf_allocator = new partition_mf_allocator(config);
if(!m_config->m_L2_config.disabled())
- m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE);
+ m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE, gpu);
unsigned int icnt_L2;
unsigned int L2_dram;
@@ -357,7 +362,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch *mf = m_L2cache->next_access();
if(mf->get_access_type() != L2_WR_ALLOC_R){ // Don't pass write allocate read request back to upper level cache
mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ 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);
}else{
if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE)
@@ -365,7 +370,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch* original_wr_mf = mf->get_original_wr_mf();
assert(original_wr_mf);
original_wr_mf->set_reply();
- original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ original_wr_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(original_wr_mf);
}
m_request_tracker.erase(mf);
@@ -379,13 +384,13 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch *mf = m_dram_L2_queue->top();
if ( !m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf) ) {
if (m_L2cache->fill_port_free()) {
- mf->set_status(IN_PARTITION_L2_FILL_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L2cache->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset);
+ mf->set_status(IN_PARTITION_L2_FILL_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2cache->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset);
m_dram_L2_queue->pop();
}
} else if ( !m_L2_icnt_queue->full() ) {
if(mf->is_write() && mf->get_type() == WRITE_ACK)
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ 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);
m_dram_L2_queue->pop();
}
@@ -406,7 +411,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
bool port_free = m_L2cache->data_port_free();
if ( !output_full && port_free ) {
std::list<cache_event> events;
- enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset,events);
+ enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset,events);
bool write_sent = was_write_sent(events);
bool read_sent = was_read_sent(events);
MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n", mf->get_addr(), status);
@@ -420,7 +425,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
delete mf;
} else {
mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ 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);
}
m_icnt_L2_queue->pop();
@@ -431,7 +436,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
} else if ( status != RESERVATION_FAIL ) {
if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || 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,gpu_sim_cycle+gpu_tot_sim_cycle);
+ 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
@@ -444,7 +449,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
}
} else {
// L2 is disabled or non-texture access to texture-only L2
- mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_dram_queue->push(mf);
m_icnt_L2_queue->pop();
}
@@ -455,7 +460,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch* mf = m_rop.front().req;
m_rop.pop();
m_icnt_L2_queue->push(mf);
- mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
}
@@ -635,6 +640,7 @@ std::vector<mem_fetch*> memory_sub_partition::breakdown_request_to_sector_reques
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);
@@ -664,13 +670,13 @@ void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle )
m_request_tracker.insert(req);
if( req->istexture() ) {
m_icnt_L2_queue->push(req);
- req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
} else {
rop_delay_t r;
r.req = req;
r.ready_cycle = cycle + m_config->rop_latency;
m_rop.push(r);
- req->set_status(IN_PARTITION_ROP_DELAY,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->set_status(IN_PARTITION_ROP_DELAY,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
}
}
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index 18c0a8b..c8a213c 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -42,12 +42,12 @@ public:
{
m_memory_config = config;
}
- virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access) const
+ virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const
{
abort();
return NULL;
}
- virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr) const;
+ virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const;
private:
const memory_config *m_memory_config;
};
@@ -58,7 +58,7 @@ private:
class memory_partition_unit
{
public:
- memory_partition_unit( unsigned partition_id, const struct memory_config *config, class memory_stats_t *stats );
+ memory_partition_unit( unsigned partition_id, const struct memory_config *config, class memory_stats_t *stats, class gpgpu_sim* gpu );
~memory_partition_unit();
bool busy() const;
@@ -93,6 +93,8 @@ public:
unsigned get_mpid() const { return m_id; }
+ class gpgpu_sim* get_mgpu() const { return m_gpu; }
+
private:
unsigned m_id;
@@ -140,12 +142,14 @@ private:
class mem_fetch* req;
};
std::list<dram_delay_t> m_dram_latency_queue;
+
+ class gpgpu_sim* m_gpu;
};
class memory_sub_partition
{
public:
- memory_sub_partition( unsigned sub_partition_id, const struct memory_config *config, class memory_stats_t *stats );
+ memory_sub_partition( unsigned sub_partition_id, const struct memory_config *config, class memory_stats_t *stats, class gpgpu_sim* gpu );
~memory_sub_partition();
unsigned get_id() const { return m_id; }
@@ -192,6 +196,7 @@ private:
const struct memory_config *m_config;
class l2_cache *m_L2cache;
class L2interface *m_L2interface;
+ class gpgpu_sim* m_gpu;
partition_mf_allocator *m_mf_allocator;
// model delay of ROP units with a fixed latency
diff --git a/src/gpgpu-sim/l2cache_trace.h b/src/gpgpu-sim/l2cache_trace.h
index 2235cdc..d2dd948 100644
--- a/src/gpgpu-sim/l2cache_trace.h
+++ b/src/gpgpu-sim/l2cache_trace.h
@@ -42,7 +42,7 @@
#define MEMPART_DPRINTF(...) do {\
if (MEMPART_DTRACE(MEMORY_PARTITION_UNIT)) {\
printf( MEMPART_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::MEMORY_PARTITION_UNIT],\
get_mpid() );\
printf(__VA_ARGS__);\
@@ -52,7 +52,7 @@
#define MEM_SUBPART_DPRINTF(...) do {\
if (MEM_SUBPART_DTRACE(MEMORY_PARTITION_UNIT)) {\
printf( MEM_SUBPART_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::MEMORY_SUBPARTITION_UNIT],\
m_id );\
printf(__VA_ARGS__);\
diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc
new file mode 100644
index 0000000..66d6648
--- /dev/null
+++ b/src/gpgpu-sim/local_interconnect.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2019, Mahmoud Khairy
+// Purdue University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <cmath>
+#include <utility>
+#include <algorithm>
+
+#include "local_interconnect.h"
+#include "mem_fetch.h"
+
+xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit)
+{
+ m_id=router_id;
+ router_type=m_type;
+ _n_mem = n_mem;
+ _n_shader = n_shader;
+ total_nodes = n_shader+n_mem;
+ in_buffers.resize(total_nodes);
+ out_buffers.resize(total_nodes);
+ next_node=0;
+ in_buffer_limit = m_in_buffer_limit;
+ out_buffer_limit = m_out_buffer_limit;
+ if(m_type == REQ_NET) {
+ active_in_buffers=n_shader;
+ active_out_buffers=n_mem;
+ }
+ else if(m_type == REPLY_NET) {
+ active_in_buffers=n_mem;
+ active_out_buffers=n_shader;
+ }
+
+ cycles = 0;
+ conflicts= 0;
+ out_buffer_full=0;
+ in_buffer_full=0;
+ out_buffer_util=0;
+ in_buffer_util=0;
+ packets_num=0;
+}
+
+
+xbar_router::~xbar_router()
+{
+
+}
+
+void xbar_router::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size)
+{
+ assert(input_deviceID < total_nodes);
+ in_buffers[input_deviceID].push(Packet(data, output_deviceID));
+ packets_num++;
+}
+
+void* xbar_router::Pop(unsigned ouput_deviceID)
+{
+ assert(ouput_deviceID < total_nodes);
+ void* data = NULL;
+
+ if(!out_buffers[ouput_deviceID].empty()) {
+ data = out_buffers[ouput_deviceID].front().data;
+ out_buffers[ouput_deviceID].pop();
+ }
+
+ return data;
+}
+
+
+bool xbar_router::Has_Buffer_In(unsigned input_deviceID, unsigned size, bool update_counter){
+
+ assert(input_deviceID < total_nodes);
+
+ bool has_buffer = (in_buffers[input_deviceID].size() + size <= in_buffer_limit);
+ if(update_counter && !has_buffer)
+ in_buffer_full++;
+
+ return has_buffer;
+
+}
+
+bool xbar_router::Has_Buffer_Out(unsigned output_deviceID, unsigned size){
+ return (out_buffers[output_deviceID].size() + size <= out_buffer_limit);
+}
+
+void xbar_router::Advance() {
+ cycles++;
+
+ vector<bool> issued(total_nodes, false);
+
+ for(unsigned i=0; i<total_nodes; ++i){
+ unsigned node_id = (i+next_node)%total_nodes;
+
+ if(!in_buffers[node_id].empty()) {
+ Packet _packet = in_buffers[node_id].front();
+ //ensure that the outbuffer has space and not issued before in this cycle
+ if(Has_Buffer_Out(_packet.output_deviceID, 1)){
+ if(!issued[_packet.output_deviceID]) {
+ out_buffers[_packet.output_deviceID].push(_packet);
+ in_buffers[node_id].pop();
+ issued[_packet.output_deviceID]=true;
+ }
+ else
+ conflicts++;
+ }
+ else
+ out_buffer_full++;
+ }
+ }
+
+ next_node = (++next_node % total_nodes);
+
+ //collect some stats about buffer util
+ for(unsigned i=0; i<total_nodes; ++i){
+ in_buffer_util+=in_buffers[i].size();
+ out_buffer_util+=out_buffers[i].size();
+ }
+}
+
+bool xbar_router::Busy() const {
+
+ for(unsigned i=0; i<total_nodes; ++i){
+ if(!in_buffers[i].empty())
+ return true;
+
+ if(!out_buffers[i].empty())
+ return true;
+ }
+ return false;
+}
+
+
+////////////////////////////////////////////////////
+/////////////LocalInterconnect/////////////////////
+
+//assume all the packets are one flit
+#define LOCAL_INCT_FLIT_SIZE 40
+
+LocalInterconnect* LocalInterconnect::New(const struct inct_config& m_localinct_config)
+{
+
+ LocalInterconnect* icnt_interface = new LocalInterconnect(m_localinct_config);
+
+ return icnt_interface;
+}
+
+LocalInterconnect::LocalInterconnect(const struct inct_config& m_localinct_config): m_inct_config(m_localinct_config){
+ n_shader=0;
+ n_mem=0;
+ n_subnets = m_localinct_config.subnets;
+}
+
+LocalInterconnect::~LocalInterconnect(){
+ for (int i=0; i<m_inct_config.subnets; ++i) {
+ delete net[i];
+ }
+}
+
+void LocalInterconnect::CreateInterconnect(unsigned m_n_shader, unsigned m_n_mem){
+ n_shader = m_n_shader;
+ n_mem = m_n_mem;
+
+ net.resize(n_subnets);
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ net[i] = new xbar_router( i, static_cast<Interconnect_type>(i), m_n_shader, m_n_mem, m_inct_config.in_buffer_limit, m_inct_config.out_buffer_limit );
+ }
+
+}
+
+
+void LocalInterconnect::Init() {
+ //empty
+ //there is nothing to do
+
+}
+
+void LocalInterconnect::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size){
+
+ unsigned subnet;
+ if (n_subnets == 1) {
+ subnet = 0;
+ } else {
+ if (input_deviceID < n_shader ) {
+ subnet = 0;
+ } else {
+ subnet = 1;
+ }
+ }
+
+ // it should have free buffer
+ //assume all the packets have size of one
+ //no flits are implemented
+ assert(net[subnet]->Has_Buffer_In(input_deviceID, 1));
+
+ net[subnet]->Push(input_deviceID, output_deviceID, data, size);
+
+}
+
+void* LocalInterconnect::Pop(unsigned ouput_deviceID){
+
+ // 0-_n_shader-1 indicates reply(network 1), otherwise request(network 0)
+ int subnet = 0;
+ if (ouput_deviceID < n_shader)
+ subnet = 1;
+
+ return net[subnet]->Pop(ouput_deviceID);
+
+}
+
+void LocalInterconnect::Advance(){
+
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ net[i]->Advance();
+ }
+
+}
+
+bool LocalInterconnect::Busy() const{
+
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ if(net[i]->Busy())
+ return true;
+ }
+ return false;
+}
+
+bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const{
+
+ bool has_buffer = false;
+
+ if ((n_subnets>1) && deviceID >= n_shader) // deviceID is memory node
+ has_buffer = net[REPLY_NET]->Has_Buffer_In(deviceID, 1, true);
+ else
+ has_buffer = net[REQ_NET]->Has_Buffer_In(deviceID, 1, true);
+
+ return has_buffer;
+
+}
+
+void LocalInterconnect::DisplayStats() const{
+
+ cout<<"Req_Network_injected_packets_num = "<<net[REQ_NET]->packets_num<<endl;
+ cout<<"Req_Network_cycles = "<<net[REQ_NET]->cycles<<endl;
+ cout<<"Req_Network_injected_packets_per_cycle = "<<(float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_conflicts_per_cycle = "<<(float)(net[REQ_NET]->conflicts) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_in_buffer_full_per_cycle = "<<(float)(net[REQ_NET]->in_buffer_full) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_in_buffer_avg_util = "<<((float)(net[REQ_NET]->in_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_in_buffers)<<endl;
+ cout<<"Req_Network_out_buffer_full_per_cycle = "<<(float)(net[REQ_NET]->out_buffer_full) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_out_buffer_avg_util = "<<((float)(net[REQ_NET]->out_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_out_buffers)<<endl;
+
+ cout<<endl;
+ cout<<"Reply_Network_injected_packets_num = "<<net[REPLY_NET]->packets_num<<endl;
+ cout<<"Reply_Network_cycles = "<<net[REPLY_NET]->cycles<<endl;
+ cout<<"Reply_Network_injected_packets_per_cycle = "<<(float)(net[REPLY_NET]->packets_num) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_conflicts_per_cycle = "<<(float)(net[REPLY_NET]->conflicts) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_in_buffer_full_per_cycle = "<<(float)(net[REPLY_NET]->in_buffer_full) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_in_buffer_avg_util = "<<((float)(net[REPLY_NET]->in_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_in_buffers)<<endl;
+ cout<<"Reply_Network_out_buffer_full_per_cycle = "<<(float)(net[REPLY_NET]->out_buffer_full) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_out_buffer_avg_util= "<<((float)(net[REPLY_NET]->out_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_out_buffers)<<endl;
+
+}
+
+void LocalInterconnect::DisplayOverallStats() const{
+
+}
+
+unsigned LocalInterconnect::GetFlitSize() const{
+ return LOCAL_INCT_FLIT_SIZE;
+}
+
+void LocalInterconnect::DisplayState(FILE* fp) const{
+
+ fprintf(fp, "GPGPU-Sim uArch: ICNT:Display State: Under implementation\n");
+}
+
diff --git a/src/gpgpu-sim/local_interconnect.h b/src/gpgpu-sim/local_interconnect.h
new file mode 100644
index 0000000..502c80d
--- /dev/null
+++ b/src/gpgpu-sim/local_interconnect.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2019, Mahmoud Khairy
+// Purdue University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef _LOCAL_INTERCONNECT_HPP_
+#define _LOCAL_INTERCONNECT_HPP_
+
+#include <vector>
+#include <queue>
+#include <iostream>
+#include <map>
+using namespace std;
+
+
+struct inct_config
+{
+
+ //config for local interconnect
+ unsigned in_buffer_limit;
+ unsigned out_buffer_limit;
+ unsigned subnets;
+};
+
+enum Interconnect_type {
+ REQ_NET=0,
+ REPLY_NET=1
+};
+class xbar_router {
+
+public:
+ xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit);
+ ~xbar_router();
+ void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size);
+ void* Pop(unsigned ouput_deviceID);
+ void Advance();
+ bool Busy() const;
+ bool Has_Buffer_In(unsigned input_deviceID, unsigned size, bool update_counter=false);
+ bool Has_Buffer_Out(unsigned output_deviceID, unsigned size);
+
+ //some stats
+ unsigned long long cycles;
+ unsigned long long conflicts;
+ unsigned long long out_buffer_full;
+ unsigned long long out_buffer_util;
+ unsigned long long in_buffer_full;
+ unsigned long long in_buffer_util;
+ unsigned long long packets_num;
+
+private:
+ struct Packet{
+ Packet(void* m_data, unsigned m_output_deviceID) {
+ data = m_data;
+ output_deviceID = m_output_deviceID;
+ }
+ void* data;
+ unsigned output_deviceID;
+ };
+ vector<queue<Packet> > in_buffers;
+ vector<queue<Packet> > out_buffers;
+ unsigned _n_shader, _n_mem, total_nodes;
+ unsigned in_buffer_limit, out_buffer_limit;
+ unsigned next_node;
+ unsigned m_id;
+ enum Interconnect_type router_type;
+ unsigned active_in_buffers,active_out_buffers;
+
+ friend class LocalInterconnect;
+
+};
+
+class LocalInterconnect {
+public:
+ LocalInterconnect(const struct inct_config& m_localinct_config);
+ ~LocalInterconnect();
+ static LocalInterconnect* New(const struct inct_config& m_inct_config);
+ void CreateInterconnect(unsigned n_shader, unsigned n_mem);
+
+ //node side functions
+ void Init();
+ void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size);
+ void* Pop(unsigned ouput_deviceID);
+ void Advance();
+ bool Busy() const;
+ bool HasBuffer(unsigned deviceID, unsigned int size) const;
+ void DisplayStats() const;
+ void DisplayOverallStats() const;
+ unsigned GetFlitSize() const;
+
+ void DisplayState(FILE* fp) const;
+
+
+protected:
+
+ const inct_config& m_inct_config;
+
+ unsigned n_shader, n_mem;
+ unsigned n_subnets;
+ vector<xbar_router *> net;
+
+};
+
+#endif
+
+
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index a260a35..c9b0484 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -40,6 +40,7 @@ mem_fetch::mem_fetch( const mem_access_t &access,
unsigned sid,
unsigned tpc,
const struct memory_config *config,
+ unsigned long long cycle,
mem_fetch *m_original_mf,
mem_fetch *m_original_wr_mf)
@@ -58,10 +59,10 @@ mem_fetch::mem_fetch( const mem_access_t &access,
config->m_address_mapping.addrdec_tlx(access.get_addr(),&m_raw_addr);
m_partition_addr = config->m_address_mapping.partition_address(access.get_addr());
m_type = m_access.is_write()?WRITE_REQUEST:READ_REQUEST;
- m_timestamp = gpu_sim_cycle + gpu_tot_sim_cycle;
+ m_timestamp = cycle;
m_timestamp2 = 0;
m_status = MEM_FETCH_INITIALIZED;
- m_status_change = gpu_sim_cycle + gpu_tot_sim_cycle;
+ m_status_change = cycle;
m_mem_config = config;
icnt_flit_size = config->icnt_flit_size;
original_mf = m_original_mf;
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index e5efffd..4eb3a52 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -56,6 +56,7 @@ public:
unsigned sid,
unsigned tpc,
const struct memory_config *config,
+ unsigned long long cycle,
mem_fetch *original_mf = NULL,
mem_fetch *original_wr_mf = NULL);
~mem_fetch();
diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index c5452b9..c7d20d1 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -42,7 +42,7 @@
#include <stdlib.h>
#include <stdio.h>
-memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_config *shader_config, const struct memory_config *mem_config )
+memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_config *shader_config, const struct memory_config *mem_config, const class gpgpu_sim* gpu )
{
assert( mem_config->m_valid );
assert( shader_config->m_valid );
@@ -67,6 +67,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
m_n_shader=n_shader;
m_memory_config=mem_config;
+ m_gpu=gpu;
total_n_access=0;
total_n_reads=0;
total_n_writes=0;
@@ -141,7 +142,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
unsigned memory_stats_t::memlatstat_done(mem_fetch *mf )
{
unsigned mf_latency;
- mf_latency = (gpu_sim_cycle+gpu_tot_sim_cycle) - mf->get_timestamp();
+ mf_latency = (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) - mf->get_timestamp();
mf_num_lat_pw++;
mf_tot_lat_pw += mf_latency;
unsigned idx = LOGB2(mf_latency);
@@ -161,7 +162,7 @@ void memory_stats_t::memlatstat_read_done(mem_fetch *mf)
if (mf_latency > mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk])
mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk] = mf_latency;
unsigned icnt2sh_latency;
- icnt2sh_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_return_timestamp();
+ icnt2sh_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_return_timestamp();
tot_icnt2sh_latency += icnt2sh_latency;
icnt2sh_lat_table[LOGB2(icnt2sh_latency)]++;
if (icnt2sh_latency > max_icnt2sh_latency)
@@ -195,7 +196,7 @@ void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf)
{
if (m_memory_config->gpgpu_memlatency_stat) {
unsigned icnt2mem_latency;
- icnt2mem_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_timestamp();
+ icnt2mem_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_timestamp();
tot_icnt2mem_latency += icnt2mem_latency;
icnt2mem_lat_table[LOGB2(icnt2mem_latency)]++;
if (icnt2mem_latency > max_icnt2mem_latency)
@@ -366,7 +367,7 @@ void memory_stats_t::memlatstat_print( unsigned n_mem, unsigned gpu_mem_n_bk )
m = 0;
printf("\n");
}
- printf("total reads: %d\n", k);
+ printf("total dram reads = %d\n", k);
if (min_bank_accesses)
printf("bank skew: %d/%d = %4.2f\n", max_bank_accesses, min_bank_accesses, (float)max_bank_accesses/min_bank_accesses);
else
@@ -404,7 +405,7 @@ void memory_stats_t::memlatstat_print( unsigned n_mem, unsigned gpu_mem_n_bk )
m = 0;
printf("\n");
}
- printf("total reads: %d\n", k);
+ printf("total dram writes = %d\n", k);
if (min_bank_accesses)
printf("bank skew: %d/%d = %4.2f\n", max_bank_accesses, min_bank_accesses, (float)max_bank_accesses/min_bank_accesses);
else
diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h
index 5b89202..b86740d 100644
--- a/src/gpgpu-sim/mem_latency_stat.h
+++ b/src/gpgpu-sim/mem_latency_stat.h
@@ -36,7 +36,8 @@ class memory_stats_t {
public:
memory_stats_t( unsigned n_shader,
const struct shader_core_config *shader_config,
- const struct memory_config *mem_config );
+ const struct memory_config *mem_config,
+ const class gpgpu_sim* gpu);
unsigned memlatstat_done( class mem_fetch *mf );
void memlatstat_read_done( class mem_fetch *mf );
@@ -51,6 +52,7 @@ public:
const struct shader_core_config *m_shader_config;
const struct memory_config *m_memory_config;
+ const class gpgpu_sim* m_gpu;
unsigned max_mrq_latency;
unsigned max_dq_latency;
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc
index ebec891..80f95c6 100644
--- a/src/gpgpu-sim/scoreboard.cc
+++ b/src/gpgpu-sim/scoreboard.cc
@@ -32,13 +32,15 @@
//Constructor
-Scoreboard::Scoreboard( unsigned sid, unsigned n_warps )
+Scoreboard::Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu )
: longopregs()
{
m_sid = sid;
//Initialize size of table
reg_table.resize(n_warps);
longopregs.resize(n_warps);
+
+ m_gpu = gpu;
}
// Print scoreboard contents
diff --git a/src/gpgpu-sim/scoreboard.h b/src/gpgpu-sim/scoreboard.h
index 4a76ea3..a4baa19 100644
--- a/src/gpgpu-sim/scoreboard.h
+++ b/src/gpgpu-sim/scoreboard.h
@@ -38,7 +38,7 @@
class Scoreboard {
public:
- Scoreboard( unsigned sid, unsigned n_warps );
+ Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu );
void reserveRegisters(const warp_inst_t *inst);
void releaseRegisters(const warp_inst_t *inst);
@@ -59,6 +59,8 @@ private:
std::vector< std::set<unsigned> > reg_table;
//Register that depend on a long operation (global, local or tex memory)
std::vector< std::set<unsigned> > longopregs;
+
+ class gpgpu_t* m_gpu;
};
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 3db988b..69b619a 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -133,7 +133,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_L1I = new read_only_cache( name,m_config->m_L1I_config,m_sid,get_shader_instruction_cache_id(),m_icnt,IN_L1I_MISS_QUEUE);
m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size));
- m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader);
+ m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu);
//scedulers
//must currently occur after all inputs have been initialized.
@@ -767,7 +767,7 @@ void shader_core_ctx::fetch()
m_inst_fetch_buffer = ifetch_buffer_t(m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid());
assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting.
m_inst_fetch_buffer.m_valid = true;
- m_warp[mf->get_wid()].set_last_fetch(gpu_sim_cycle);
+ m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle);
delete mf;
}
else {
@@ -815,17 +815,19 @@ void shader_core_ctx::fetch()
warp_id,
m_sid,
m_tpc,
- m_memory_config );
+ m_memory_config,
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle
+ );
std::list<cache_event> events;
- enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events);
if( status == MISS ) {
m_last_warp_fetched=warp_id;
m_warp[warp_id].set_imiss_pending();
- m_warp[warp_id].set_last_fetch(gpu_sim_cycle);
+ m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle);
} else if( status == HIT ) {
m_last_warp_fetched=warp_id;
m_inst_fetch_buffer = ifetch_buffer_t(pc,nbytes,warp_id);
- m_warp[warp_id].set_last_fetch(gpu_sim_cycle);
+ m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle);
delete mf;
} else {
m_last_warp_fetched=warp_id;
@@ -859,7 +861,7 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t*
m_warp[warp_id].ibuffer_free();
assert(next_inst->valid());
**pipe_reg = *next_inst; // static instruction information
- (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information
+ (*pipe_reg)->issue( active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information
m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++;
func_exec_inst( **pipe_reg );
if( next_inst->op == BARRIER_OP ){
@@ -1514,7 +1516,7 @@ void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst)
m_stats->m_num_sim_winsn[m_sid]++;
m_gpu->gpu_sim_insn += inst.active_count();
- inst.completed(gpu_tot_sim_cycle + gpu_sim_cycle);
+ inst.completed(m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
}
void shader_core_ctx::writeback()
@@ -1552,9 +1554,9 @@ void shader_core_ctx::writeback()
m_warp[warp_id].dec_inst_in_pipeline();
warp_inst_complete(*pipe_reg);
m_gpu->gpu_sim_insn_last_update_sid = m_sid;
- m_gpu->gpu_sim_insn_last_update = gpu_sim_cycle;
- m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
- m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle;
+ m_gpu->gpu_sim_insn_last_update = m_gpu->gpu_sim_cycle;
+ m_last_inst_gpu_sim_cycle = m_gpu->gpu_sim_cycle;
+ m_last_inst_gpu_tot_sim_cycle = m_gpu->gpu_tot_sim_cycle;
pipe_reg->clear();
preg = m_pipeline_reg[EX_WB].get_ready();
pipe_reg = (preg==NULL)? NULL:*preg;
@@ -1633,9 +1635,9 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue( cache_t *cache, war
return DATA_PORT_STALL;
//const mem_access_t &access = inst.accessq_back();
- mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back());
+ mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
std::list<cache_event> events;
- enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
return process_cache_access( cache, mf->get_addr(), inst, events, mf, status );
}
@@ -1645,7 +1647,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c
if( inst.accessq_empty() )
return result;
- mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back());
+ mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
if(m_config->m_L1D_config.l1_latency > 0)
{
@@ -1675,7 +1677,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c
else
{
std::list<cache_event> events;
- enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
return process_cache_access( cache, mf->get_addr(), inst, events, mf, status );
}
}
@@ -1687,7 +1689,7 @@ void ldst_unit::L1_latency_queue_cycle()
{
mem_fetch* mf_next = l1_latency_queue[0];
std::list<cache_event> events;
- enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
bool write_sent = was_write_sent(events);
bool read_sent = was_read_sent(events);
@@ -1804,7 +1806,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
if( m_icnt->full(size, inst.is_store() || inst.isatomic()) ) {
stall_cond = ICNT_RC_FAIL;
} else {
- mem_fetch *mf = m_mf_allocator->alloc(inst,access);
+ mem_fetch *mf = m_mf_allocator->alloc(inst,access,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_icnt->push(mf);
inst.accessq_pop_back();
//inst.clear_active( access.get_warp_mask() );
@@ -1840,7 +1842,7 @@ bool ldst_unit::response_buffer_full() const
void ldst_unit::fill( mem_fetch *mf )
{
- mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.push_back(mf);
}
@@ -1893,6 +1895,17 @@ void tensor_core::issue( register_set& source_reg )
pipelined_simd_unit::issue(source_reg);
}
+unsigned pipelined_simd_unit::get_active_lanes_in_pipeline(){
+ active_mask_t active_lanes;
+ active_lanes.reset();
+ if(m_core->get_gpu()->get_config().g_power_simulation_enabled){
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ){
+ if( !m_pipeline_reg[stage]->empty() )
+ active_lanes|=m_pipeline_reg[stage]->get_active_mask();
+ }
+ }
+ return active_lanes.count();
+}
void ldst_unit::active_lanes_in_pipeline(){
unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
@@ -1946,13 +1959,13 @@ sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,sh
}
dp_unit::dp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
- : pipelined_simd_unit(result_port,config,config->max_sfu_latency,core)
+ : pipelined_simd_unit(result_port,config,config->max_dp_latency,core)
{
m_name = "DP ";
}
int_unit::int_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
- : pipelined_simd_unit(result_port,config,config->max_sp_latency,core)
+ : pipelined_simd_unit(result_port,config,config->max_int_latency,core)
{
m_name = "INT ";
}
@@ -1993,19 +2006,25 @@ pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shade
for( unsigned i=0; i < m_pipeline_depth; i++ )
m_pipeline_reg[i] = new warp_inst_t( config );
m_core=core;
+ active_insts_in_pipeline=0;
}
void pipelined_simd_unit::cycle()
{
if( !m_pipeline_reg[0]->empty() ){
m_result_port->move_in(m_pipeline_reg[0]);
+ assert(active_insts_in_pipeline > 0);
+ active_insts_in_pipeline--;
+ }
+ if(active_insts_in_pipeline){
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
+ move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
}
- for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
- move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
if( !m_dispatch_reg->empty() ) {
if( !m_dispatch_reg->dispatch_delay()){
int start_stage = m_dispatch_reg->latency - m_dispatch_reg->initiation_interval;
move_warp(m_pipeline_reg[start_stage],m_dispatch_reg);
+ active_insts_in_pipeline++;
}
}
occupied >>=1;
@@ -2098,7 +2117,8 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt,
get_shader_normal_cache_id(),
m_icnt,
m_mf_allocator,
- IN_L1D_MISS_QUEUE );
+ IN_L1D_MISS_QUEUE,
+ core->get_gpu());
if(m_config->m_L1D_config.l1_latency > 0)
{
@@ -2185,8 +2205,8 @@ void ldst_unit::writeback()
m_core->warp_inst_complete(m_next_wb);
}
m_next_wb.clear();
- m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
- m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle;
+ m_last_inst_gpu_sim_cycle = m_core->get_gpu()->gpu_sim_cycle;
+ m_last_inst_gpu_tot_sim_cycle = m_core->get_gpu()->gpu_tot_sim_cycle;
}
}
@@ -2294,13 +2314,13 @@ void ldst_unit::cycle()
mem_fetch *mf = m_response_fifo.front();
if (mf->get_access_type() == TEXTURE_ACC_R) {
if (m_L1T->fill_port_free()) {
- m_L1T->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1T->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
} else if (mf->get_access_type() == CONST_ACC_R) {
if (m_L1C->fill_port_free()) {
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L1C->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
+ m_L1C->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
} else {
@@ -2320,13 +2340,13 @@ void ldst_unit::cycle()
}
if( bypassL1D ) {
if ( m_next_global == NULL ) {
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
m_next_global = mf;
}
} else {
if (m_L1D->fill_port_free()) {
- m_L1D->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1D->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
}
@@ -2415,7 +2435,7 @@ void shader_core_ctx::register_cta_thread_exit( unsigned cta_num, kernel_info_t
shader_CTA_count_unlog(m_sid, 1);
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Finished CTA #%d (%lld,%lld), %u CTAs running\n",
- cta_num, gpu_sim_cycle, gpu_tot_sim_cycle, m_n_active_cta);
+ cta_num, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle, m_n_active_cta);
if( m_n_active_cta == 0 ) {
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Empty (last released kernel %u \'%s\').\n",
@@ -2525,13 +2545,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1I_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1I_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1I_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1I_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1I_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1I_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1I_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1I_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1I_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1I_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
// L1D
@@ -2542,18 +2562,18 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++){
m_cluster[i]->get_L1D_sub_stats(css);
- fprintf( stdout, "\tL1D_cache_core[%d]: Access = %d, Miss = %d, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
+ fprintf( stdout, "\tL1D_cache_core[%d]: Access = %llu, Miss = %llu, Miss_rate = %.3lf, Pending_hits = %llu, Reservation_fails = %llu\n",
i, css.accesses, css.misses, (double)css.misses / (double)css.accesses, css.pending_hits, css.res_fails);
total_css += css;
}
- fprintf(fout, "\tL1D_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1D_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1D_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1D_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1D_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1D_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1D_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1D_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1D_total_cache_reservation_fails = %llu\n", total_css.res_fails);
total_css.print_port_stats(fout, "\tL1D_cache");
}
@@ -2566,13 +2586,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1C_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1C_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1C_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1C_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1C_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1C_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1C_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1C_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1C_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1C_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
// L1T
@@ -2584,13 +2604,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1T_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1T_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1T_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1T_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1T_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1T_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1T_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1T_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1T_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1T_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
}
@@ -2806,7 +2826,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) con
{
fprintf(fout, "=================================================\n");
fprintf(fout, "shader %u at cycle %Lu+%Lu (%u threads running)\n", m_sid,
- gpu_tot_sim_cycle, gpu_sim_cycle, m_not_completed);
+ m_gpu->gpu_tot_sim_cycle, m_gpu->gpu_sim_cycle, m_not_completed);
fprintf(fout, "=================================================\n");
dump_warp_state(fout);
@@ -2949,7 +2969,7 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
abort();
}
- if(adpative_volta_cache_config && !k.volta_cache_config_set) {
+ if(adaptive_volta_cache_config && !k.volta_cache_config_set) {
//For Volta, we assign the remaining shared memory to L1 cache
//For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
unsigned total_shmed = kernel_info->smem * result;
@@ -2981,8 +3001,53 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
return result;
}
+void shader_core_config::set_pipeline_latency() {
+
+ //calculate the max latency based on the input
+
+ unsigned int_latency[5];
+ unsigned fp_latency[5];
+ unsigned dp_latency[5];
+ unsigned sfu_latency;
+ unsigned tensor_latency;
+
+ /*
+ * [0] ADD,SUB
+ * [1] MAX,Min
+ * [2] MUL
+ * [3] MAD
+ * [4] DIV
+ */
+ sscanf(opcode_latency_int, "%u,%u,%u,%u,%u",
+ &int_latency[0],&int_latency[1],&int_latency[2],
+ &int_latency[3],&int_latency[4]);
+ sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u",
+ &fp_latency[0],&fp_latency[1],&fp_latency[2],
+ &fp_latency[3],&fp_latency[4]);
+ sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u",
+ &dp_latency[0],&dp_latency[1],&dp_latency[2],
+ &dp_latency[3],&dp_latency[4]);
+ sscanf(opcode_latency_sfu, "%u",
+ &sfu_latency);
+ sscanf(opcode_latency_tensor, "%u",
+ &tensor_latency);
+
+ //all div operation are executed on sfu
+ //assume that the max latency are dp div or normal sfu_latency
+ max_sfu_latency = std::max(dp_latency[4],sfu_latency);
+ //assume that the max operation has the max latency
+ max_sp_latency = fp_latency[1];
+ max_int_latency = int_latency[1];
+ max_dp_latency = dp_latency[1];
+ max_tensor_core_latency = tensor_latency;
+
+}
+
void shader_core_ctx::cycle()
{
+ if(!isactive() && get_not_completed() == 0)
+ return;
+
m_stats->shader_cycles[m_sid]++;
writeback();
execute();
@@ -3159,7 +3224,7 @@ void barrier_set_t::warp_reaches_barrier(unsigned cta_id,unsigned warp_id,warp_i
cta_to_warp_t::iterator w=m_cta_to_warps.find(cta_id);
if( w == m_cta_to_warps.end() ) { // cta is active
- printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, gpu_tot_sim_cycle, gpu_sim_cycle );
+ printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, m_shader->get_gpu()->gpu_tot_sim_cycle, m_shader->get_gpu()->gpu_sim_cycle );
dump();
abort();
}
@@ -3332,8 +3397,8 @@ bool shader_core_ctx::fetch_unit_response_buffer_full() const
void shader_core_ctx::accept_fetch_response( mem_fetch *mf )
{
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L1I->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L1I->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
bool shader_core_ctx::ldst_unit_response_buffer_full() const
@@ -3895,7 +3960,7 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf)
}
m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size);
unsigned destination = mf->get_sub_partition_id();
- mf->set_status(IN_ICNT_TO_MEM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_ICNT_TO_MEM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
if (!mf->get_is_write() && !mf->isatomic())
::icnt_push(m_cluster_id, m_config->mem2device(destination), (void*)mf, mf->get_ctrl_size() );
else
@@ -3934,7 +3999,7 @@ void simt_core_cluster::icnt_cycle()
// - For write-ack, the packet only has control metadata
unsigned int packet_size = (mf->get_is_write())? mf->get_ctrl_size() : mf->size();
m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size);
- mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
//m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
m_response_fifo.push_back(mf);
m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false);
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 9abd223..fde87b6 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -55,7 +55,6 @@
#include "traffic_breakdown.h"
-
#define NO_OP_FLAG 0xFF
/* READ_PACKET_SIZE:
@@ -1073,16 +1072,8 @@ public:
//modifiers
virtual void cycle();
virtual void issue( register_set& source_reg );
- virtual unsigned get_active_lanes_in_pipeline()
- {
- active_mask_t active_lanes;
- active_lanes.reset();
- for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ){
- if( !m_pipeline_reg[stage]->empty() )
- active_lanes|=m_pipeline_reg[stage]->get_active_mask();
- }
- return active_lanes.count();
- }
+ virtual unsigned get_active_lanes_in_pipeline();
+
virtual void active_lanes_in_pipeline() = 0;
/*
virtual void issue( register_set& source_reg )
@@ -1113,6 +1104,9 @@ protected:
warp_inst_t **m_pipeline_reg;
register_set *m_result_port;
class shader_core_ctx *m_core;
+
+ unsigned active_insts_in_pipeline;
+
};
class sfu : public pipelined_simd_unit
@@ -1413,10 +1407,8 @@ struct shader_core_config : public core_config
}
max_warps_per_shader = n_thread_per_shader/warp_size;
assert( !(n_thread_per_shader % warp_size) );
- max_sfu_latency = 512;
- max_sp_latency = 32;
-
- max_tensor_core_latency = 64;
+
+ set_pipeline_latency();
m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone);
m_L1T_config.init(m_L1T_config.m_config_string,FuncCachePreferNone);
@@ -1432,6 +1424,7 @@ struct shader_core_config : public core_config
unsigned sid_to_cluster( unsigned sid ) const { return sid / n_simt_cores_per_cluster; }
unsigned sid_to_cid( unsigned sid ) const { return sid % n_simt_cores_per_cluster; }
unsigned cid_to_sid( unsigned cid, unsigned cluster_id ) const { return cluster_id*n_simt_cores_per_cluster + cid; }
+ void set_pipeline_latency();
// data
char *gpgpu_shader_core_pipeline_opt;
@@ -1506,7 +1499,9 @@ struct shader_core_config : public core_config
bool sub_core_model;
unsigned max_sp_latency;
+ unsigned max_int_latency;
unsigned max_sfu_latency;
+ unsigned max_dp_latency;
unsigned max_tensor_core_latency;
unsigned n_simt_cores_per_cluster;
@@ -1524,6 +1519,7 @@ struct shader_core_config : public core_config
bool gpgpu_concurrent_kernel_sm;
bool adpative_volta_cache_config;
+
};
struct shader_core_stats_pod {
@@ -1734,7 +1730,7 @@ public:
m_cluster_id = cluster_id;
m_memory_config = config;
}
- mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const
+ mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const
{
mem_access_t access( type, addr, size, wr );
mem_fetch *mf = new mem_fetch( access,
@@ -1743,11 +1739,12 @@ public:
-1,
m_core_id,
m_cluster_id,
- m_memory_config );
+ m_memory_config,
+ cycle);
return mf;
}
- mem_fetch *alloc( const warp_inst_t &inst, const mem_access_t &access ) 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;
mem_fetch *mf = new mem_fetch(access,
@@ -1756,7 +1753,8 @@ public:
inst.warp_id(),
m_core_id,
m_cluster_id,
- m_memory_config);
+ m_memory_config,
+ cycle);
return mf;
}
diff --git a/src/gpgpu-sim/shader_trace.h b/src/gpgpu-sim/shader_trace.h
index de3e059..ac4e894 100644
--- a/src/gpgpu-sim/shader_trace.h
+++ b/src/gpgpu-sim/shader_trace.h
@@ -44,7 +44,7 @@
#define SHADER_DPRINTF(x, ...) do {\
if (SHADER_DTRACE(x)) {\
printf( SHADER_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::x],\
get_sid() );\
printf(__VA_ARGS__);\
@@ -56,7 +56,7 @@
#define SCHED_DPRINTF(...) do {\
if (SHADER_DTRACE(WARP_SCHEDULER)) {\
printf( SCHED_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_shader->get_gpu()->gpu_sim_cycle + m_shader->get_gpu()->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::WARP_SCHEDULER],\
get_sid(),\
m_id );\