summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gpgpu-sim/addrdec.cc252
-rw-r--r--src/gpgpu-sim/addrdec.h55
-rw-r--r--src/gpgpu-sim/dram.cc85
-rw-r--r--src/gpgpu-sim/dram.h22
-rw-r--r--src/gpgpu-sim/dram_sched.cc58
-rw-r--r--src/gpgpu-sim/dram_sched.h6
-rw-r--r--src/gpgpu-sim/gpu-cache.cc162
-rw-r--r--src/gpgpu-sim/gpu-cache.h71
-rw-r--r--src/gpgpu-sim/gpu-sim.cc73
-rw-r--r--src/gpgpu-sim/gpu-sim.h50
-rw-r--r--src/gpgpu-sim/l2cache.cc34
-rw-r--r--src/gpgpu-sim/l2cache.h6
-rw-r--r--src/gpgpu-sim/mem_fetch.cc6
-rw-r--r--src/gpgpu-sim/mem_fetch.h19
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc73
-rw-r--r--src/gpgpu-sim/mem_latency_stat.h10
-rw-r--r--src/gpgpu-sim/shader.cc40
-rw-r--r--src/gpgpu-sim/shader.h7
18 files changed, 463 insertions, 566 deletions
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc
index f3a9091..464aff0 100644
--- a/src/gpgpu-sim/addrdec.cc
+++ b/src/gpgpu-sim/addrdec.cc
@@ -1,5 +1,5 @@
/*
- * addrdec.c
+ * addrdec.cc
*
* Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung, Ali Bakhoda,
* George L. Yuan and the University of British Columbia
@@ -68,84 +68,39 @@
#include "gpu-sim.h"
#include "../option_parser.h"
-int ADDR_CHIP_S = 10;
-long int powli( long int x, long int y ) // compute x to the y
-{
- long int r = 1;
- int i;
- for (i = 0; i < y; ++i ) {
- r *= x;
- }
- return r;
-}
-
-void addrdec_display(addrdec_t *a) {
- //printf("DRAM: unused:%x chip:%x row:%x col:%x bk:%x\n",
- // a.dram.unused, a.dram.chip, GET_ROW(a), GET_COL(a), a.dram.bk);
- if (a->chip) printf("\tchip:%x ", a->chip);
- if (a->row) printf("\trow:%x ", a->row);
- if (a->col) printf("\tcol:%x ", a->col);
- if (a->bk) printf("\tbk:%x ", a->bk);
- if (a->burst) printf("\tburst:%x ", a->burst);
-}
+static long int powli( long int x, long int y );
+static unsigned int LOGB2_32( unsigned int v );
+static new_addr_type addrdec_packbits( new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low);
+static void addrdec_getmasklimit(new_addr_type mask, unsigned char *high, unsigned char *low);
-unsigned long long int addrdec_packbits(unsigned long long int mask,
- unsigned long long int val,
- unsigned char high, unsigned char low)
+linear_to_raw_address_translation::linear_to_raw_address_translation()
{
- int i, pos;
- unsigned long long int out;
- out = 0;
- pos = 0;
- for (i=low;i<high;i++) {
- if ((mask & ((unsigned long long int)1<<i)) != 0) {
- out |= ((val & ((unsigned long long int)1<<i)) >> i) << pos;
- pos++;
- }
- // printf("%02d: %016llx %d\n",i,out,pos);
- }
-
- return out;
+ addrdec_option = NULL;
+ ADDR_CHIP_S = 10;
+ memset(addrdec_mklow,0,N_ADDRDEC);
+ memset(addrdec_mkhigh,64,N_ADDRDEC);
+ addrdec_mask[0] = 0x0000000000001C00;
+ addrdec_mask[1] = 0x0000000000000300;
+ addrdec_mask[2] = 0x000000000FFF0000;
+ addrdec_mask[3] = 0x000000000000E0FF;
+ addrdec_mask[4] = 0x000000000000000F;
}
-unsigned long long int addrdec_mask[5] = {
- 0x0000000000001C00,
- 0x0000000000000300,
- 0x000000000FFF0000,
- 0x000000000000E0FF,
- 0x000000000000000F
-};
-
-void addrdec_getmasklimit(unsigned long long int mask, unsigned char *high, unsigned char *low)
+void linear_to_raw_address_translation::addrdec_setoption(option_parser_t opp)
{
- *high = 64;
- *low = 0;
- int i;
- int low_found = 0;
-
- for (i=0;i<64;i++) {
- if ((mask & ((unsigned long long int)1<<i)) != 0) {
- if (low_found) {
- *high = i + 1;
- } else {
- *high = i + 1;
- *low = i;
- low_found = 1;
- }
- }
- // printf("%02d: %016llx %d\n",i,out,pos);
- }
+ option_parser_register(opp, "-gpgpu_mem_addr_mapping", OPT_CSTR, &addrdec_option,
+ "mapping memory address to dram model {dramid@<start bit>;<memory address map>}",
+ NULL);
}
-unsigned char addrdec_mklow[5] = { 0, 0, 0, 0, 0};
-unsigned char addrdec_mkhigh[5] = { 64, 64, 64, 64, 64};
-
-static unsigned int gap;
-static int Nchips;
+new_addr_type linear_to_raw_address_translation::partition_address( new_addr_type addr ) const
+{
+ return addrdec_packbits( ~addrdec_mask[CHIP], addr, 64, 0 );
+}
-void addrdec_tlx(unsigned long long int addr, addrdec_t *tlx)
+void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const
{
unsigned long long int addr_for_chip,rest_of_addr;
if (!gap) {
@@ -174,31 +129,7 @@ void addrdec_tlx(unsigned long long int addr, addrdec_t *tlx)
}
}
-unsigned int LOGB2_32( unsigned int v ) {
- unsigned int shift;
- unsigned int r;
-
- r = 0;
-
- shift = (( v & 0xFFFF0000) != 0 ) << 4; v >>= shift; r |= shift;
- shift = (( v & 0xFF00 ) != 0 ) << 3; v >>= shift; r |= shift;
- shift = (( v & 0xF0 ) != 0 ) << 2; v >>= shift; r |= shift;
- shift = (( v & 0xC ) != 0 ) << 1; v >>= shift; r |= shift;
- shift = (( v & 0x2 ) != 0 ) << 0; v >>= shift; r |= shift;
-
- return r;
-}
-
-
-static char *addrdec_option;
-void addrdec_setoption(option_parser_t opp)
-{
- option_parser_register(opp, "-gpgpu_mem_addr_mapping", OPT_CSTR, &addrdec_option,
- "mapping memory address to dram model {dramid@<start bit>;<memory address map>}",
- NULL);
-}
-
-void addrdec_parseoption(const char *option)
+void linear_to_raw_address_translation::addrdec_parseoption(const char *option)
{
unsigned int dramid_start = 0;
int dramid_parsed = sscanf(option, "dramid@%d", &dramid_start);
@@ -248,15 +179,14 @@ void addrdec_parseoption(const char *option)
}
}
-
-void addrdec_setnchip(unsigned int nchips)
+void linear_to_raw_address_translation::init(unsigned int nchips)
{
unsigned i;
unsigned long long int mask;
- unsigned int nchipbits = LOGB2_32(nchips);
+ unsigned int nchipbits = ::LOGB2_32(nchips);
Nchips = nchips;
- gap = (nchips - powli(2,nchipbits));
+ gap = (nchips - ::powli(2,nchipbits));
if (gap) {
nchipbits++;
}
@@ -359,9 +289,8 @@ void addrdec_setnchip(unsigned int nchips)
break;
}
- if (addrdec_option != NULL) {
+ if (addrdec_option != NULL)
addrdec_parseoption(addrdec_option);
- }
if (ADDR_CHIP_S != -1) {
mask = ((unsigned long long int)1 << ADDR_CHIP_S) - 1;
@@ -391,80 +320,71 @@ void addrdec_setnchip(unsigned int nchips)
printf("addr_dec_mask[BURST] = %016llx \thigh:%d low:%d\n", addrdec_mask[BURST], addrdec_mkhigh[BURST], addrdec_mklow[BURST]);
}
-#ifdef UNIT_TEST
+void addrdec_t::print( FILE *fp ) const
+{
+ if (chip) fprintf(fp,"\tchip:%x ", chip);
+ if (row) fprintf(fp,"\trow:%x ", row);
+ if (col) fprintf(fp,"\tcol:%x ", col);
+ if (bk) fprintf(fp,"\tbk:%x ", bk);
+ if (burst) fprintf(fp,"\tburst:%x ", burst);
+}
-int main () {
- unsigned int tb = 1;
- unsigned pos;
- addrdec_t_o tlx;
- printf("DRAM: %d %d %d %d %d %d %d\n",
- D_COLL, D_BK, D_COLU, D_ROWL, D_CHIP, D_ROWU, D_UNUSED);
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- tlx.plain = tb;
- addrdec_fetch(tlx);
- addrdec_dram(tlx);
- printf("\n");
+static long int powli( long int x, long int y ) // compute x to the y
+{
+ long int r = 1;
+ int i;
+ for (i = 0; i < y; ++i ) {
+ r *= x;
}
+ return r;
+}
- unsigned long long int packed;
- packed = addrdec_packbits(0xFFFF0000FFFF0000, 0x2244113322441133);
- assert (packed == 0x22442244);
- printf("%016llx\n", packed);
+static unsigned int LOGB2_32( unsigned int v )
+{
+ unsigned int shift;
+ unsigned int r;
- packed = addrdec_packbits(0x5555555555555555, 0x3333333333333333);
- assert (packed == 0x55555555);
- printf("%016llx\n", packed);
+ r = 0;
- packed = addrdec_packbits(0x5555555555555555, 0x6363636363636363);
- assert (packed == 0x99999999);
- printf("%016llx\n", packed);
+ shift = (( v & 0xFFFF0000) != 0 ) << 4; v >>= shift; r |= shift;
+ shift = (( v & 0xFF00 ) != 0 ) << 3; v >>= shift; r |= shift;
+ shift = (( v & 0xF0 ) != 0 ) << 2; v >>= shift; r |= shift;
+ shift = (( v & 0xC ) != 0 ) << 1; v >>= shift; r |= shift;
+ shift = (( v & 0x2 ) != 0 ) << 0; v >>= shift; r |= shift;
- addrdec_t tls;
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
- }
+ return r;
+}
- addrdec_setnchip(32);
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
- }
- addrdec_setnchip(16);
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
- }
- addrdec_setnchip(8);
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
- }
- addrdec_setnchip(7);
- for (tb=1, pos=0; tb!=0; tb <<= 1, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
+static new_addr_type addrdec_packbits( new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low)
+{
+ unsigned pos=0;
+ new_addr_type result = 0;
+ for (unsigned i=low;i<high;i++) {
+ if ((mask & ((unsigned long long int)1<<i)) != 0) {
+ result |= ((val & ((unsigned long long int)1<<i)) >> i) << pos;
+ pos++;
+ }
}
-/* addrdec_setnchip(6);
- for(tb=1, pos=0; tb!=0; tb ++, pos++) {
- printf("%08lx|%02d =>", tb,pos);
- addrdec_tlx(tb, &tls);
- addrdec_display(&tls);
- printf("\n");
- }*/
- return 0;
+ return result;
}
-#endif
+static void addrdec_getmasklimit(new_addr_type mask, unsigned char *high, unsigned char *low)
+{
+ *high = 64;
+ *low = 0;
+ int i;
+ int low_found = 0;
+
+ for (i=0;i<64;i++) {
+ if ((mask & ((unsigned long long int)1<<i)) != 0) {
+ if (low_found) {
+ *high = i + 1;
+ } else {
+ *high = i + 1;
+ *low = i;
+ low_found = 1;
+ }
+ }
+ }
+}
diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h
index 8315bc9..60cbcf1 100644
--- a/src/gpgpu-sim/addrdec.h
+++ b/src/gpgpu-sim/addrdec.h
@@ -71,28 +71,49 @@
#ifndef ADDRDEC_H
#define ADDRDEC_H
-enum {
- CHIP = 0,
- BK = 1,
- ROW = 2,
- COL = 3,
- BURST = 4,
- N_ADDRDEC
-};
+#include "../abstract_hardware_model.h"
-typedef struct {
+struct addrdec_t {
+ void print( FILE *fp ) const;
+
unsigned chip;
unsigned bk;
unsigned row;
unsigned col;
unsigned burst;
-} addrdec_t;
+};
+
+class linear_to_raw_address_translation {
+public:
+ linear_to_raw_address_translation();
+ void addrdec_setoption(option_parser_t opp);
+ void init(unsigned int nchips);
+
+ // accessors
+ void addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const;
+ new_addr_type partition_address( new_addr_type addr ) const;
+
+private:
+ void addrdec_parseoption(const char *option);
+
+ enum {
+ CHIP = 0,
+ BK = 1,
+ ROW = 2,
+ COL = 3,
+ BURST = 4,
+ N_ADDRDEC
+ };
+
+ const char *addrdec_option;
+
+ int ADDR_CHIP_S;
+ unsigned char addrdec_mklow[N_ADDRDEC];
+ unsigned char addrdec_mkhigh[N_ADDRDEC];
+ new_addr_type addrdec_mask[N_ADDRDEC];
+
+ unsigned int gap;
+ int Nchips;
+};
-void addrdec_tlx(unsigned long long int addr, addrdec_t *tlx);
-void addrdec_setnchip(unsigned int nchips);
-void addrdec_setoption(option_parser_t opp);
-void addrdec_parseoption(const char *option);
-extern unsigned long long int addrdec_packbits(unsigned long long int mask,
- unsigned long long int val,
- unsigned char high, unsigned char low);
#endif
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index e798724..9f79c7e 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -77,21 +77,12 @@ int PRINT_CYCLE = 0;
template class fifo_pipeline<mem_fetch>;
template class fifo_pipeline<dram_req_t>;
-dram_t::dram_t( unsigned int partition_id, struct memory_config *config )
+dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, memory_stats_t *stats )
{
id = partition_id;
- m_stats = NULL;
+ m_stats = stats;
m_config = config;
- BL=m_config->gpgpu_dram_burst_length;
- busW=m_config->gpgpu_dram_buswidth;
-
- sscanf(m_config->gpgpu_dram_timing_opt,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",&nbk,&tCCD,&tRRD,&tRCD,&tRAS,&tRP,&tRC,&CL,&WL,&tWTR);
- m_config->gpu_mem_n_bk = nbk;
-
- tRCDWR = tRCD - (WL + 1); //formula given in datasheet
- tRTW = (CL+(BL/2)+2-WL); //read to write time according to datasheet
-
CCDc = 0;
RRDc = 0;
RTWc = 0;
@@ -99,20 +90,20 @@ dram_t::dram_t( unsigned int partition_id, struct memory_config *config )
rw = READ; //read mode is default
- bk = (bank_t**) calloc(sizeof(bank_t*),nbk);
- bk[0] = (bank_t*) calloc(sizeof(bank_t),nbk);
- for (unsigned i=1;i<nbk;i++)
+ bk = (bank_t**) calloc(sizeof(bank_t*),m_config->nbk);
+ bk[0] = (bank_t*) calloc(sizeof(bank_t),m_config->nbk);
+ for (unsigned i=1;i<m_config->nbk;i++)
bk[i] = bk[0] + i;
- for (unsigned i=0;i<nbk;i++)
+ for (unsigned i=0;i<m_config->nbk;i++)
bk[i]->state = BANK_IDLE;
prio = 0;
- rwq = new fifo_pipeline<dram_req_t>("rwq",CL,CL+1,gpu_sim_cycle);
+ rwq = new fifo_pipeline<dram_req_t>("rwq",m_config->CL,m_config->CL+1,gpu_sim_cycle);
mrqq = new fifo_pipeline<dram_req_t>("mrqq",0,0,gpu_sim_cycle);
returnq = new fifo_pipeline<mem_fetch>("dramreturnq",0,m_config->gpgpu_dram_sched_queue_size,gpu_sim_cycle);
m_fast_ideal_scheduler = NULL;
if ( m_config->scheduler_type == DRAM_IDEAL_FAST )
- m_fast_ideal_scheduler = new ideal_dram_scheduler(this);
+ m_fast_ideal_scheduler = new ideal_dram_scheduler(m_config,this,stats);
n_cmd = 0;
n_activity = 0;
n_nop = 0;
@@ -265,10 +256,10 @@ void dram_t::issueCMD()
ave_mrqs += mrqq->get_length();
ave_mrqs_partial += mrqq->get_length();
}
- k=nbk;
+ k=m_config->nbk;
// check if any bank is ready to issue a new read
- for (i=0;i<nbk;i++) {
- j = (i + prio) % nbk;
+ for (i=0;i<m_config->nbk;i++) {
+ j = (i + prio) % m_config->nbk;
if (bk[j]->mrq) { //if currently servicing a memory request
// correct row activated for a READ
if ( !issued && !CCDc && !bk[j]->RCDc &&
@@ -278,22 +269,22 @@ void dram_t::issueCMD()
!rwq->full() ) {
if (rw==WRITE) {
rw=READ;
- rwq->set_min_length(CL,gpu_sim_cycle);
+ rwq->set_min_length(m_config->CL,gpu_sim_cycle);
}
rwq->push(bk[j]->mrq,gpu_sim_cycle);
- bk[j]->mrq->txbytes += BL * busW * gpu_n_mem_per_ctrlr; //16 bytes
- CCDc = tCCD;
- RTWc = tRTW;
+ bk[j]->mrq->txbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; //16 bytes
+ CCDc = m_config->tCCD;
+ RTWc = m_config->tRTW;
issued = 1;
n_rd++;
- bwutil+= BL/2;
- bwutil_partial += BL/2;
+ bwutil+= m_config->BL/2;
+ bwutil_partial += m_config->BL/2;
bk[j]->n_access++;
#ifdef DRAM_VERIFY
PRINT_CYCLE=1;
printf("\tRD Bk:%d Row:%03x Col:%03x \n",
j, bk[j]->curr_row,
- bk[j]->mrq->col+bk[j]->mrq->txbytes-BL*busW);
+ bk[j]->mrq->col+bk[j]->mrq->txbytes-m_config->BL*m_config->busW);
#endif
// transfer done
if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
@@ -308,21 +299,21 @@ void dram_t::issueCMD()
!rwq->full() ) {
if (rw==READ) {
rw=WRITE;
- rwq->set_min_length(WL,gpu_sim_cycle);
+ rwq->set_min_length(m_config->WL,gpu_sim_cycle);
}
rwq->push(bk[j]->mrq,gpu_sim_cycle);
- bk[j]->mrq->txbytes += BL * busW * gpu_n_mem_per_ctrlr; /*16 bytes*/
- CCDc = tCCD;
+ bk[j]->mrq->txbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; /*16 bytes*/
+ CCDc = m_config->tCCD;
issued = 1;
n_wr++;
bwutil+=2;
- bwutil_partial += BL/2;
+ bwutil_partial += m_config->BL/2;
#ifdef DRAM_VERIFY
PRINT_CYCLE=1;
printf("\tWR Bk:%d Row:%03x Col:%03x \n",
j, bk[j]->curr_row,
- bk[j]->mrq->col+bk[j]->mrq->txbytes-BL*busW);
+ bk[j]->mrq->col+bk[j]->mrq->txbytes-m_config->BL*m_config->busW);
#endif
// transfer done
if ( !(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes) ) {
@@ -343,12 +334,12 @@ void dram_t::issueCMD()
// activate the row with current memory request
bk[j]->curr_row = bk[j]->mrq->row;
bk[j]->state = BANK_ACTIVE;
- RRDc = tRRD;
- bk[j]->RCDc = tRCD;
- bk[j]->RCDWRc = tRCDWR;
- bk[j]->RASc = tRAS;
- bk[j]->RCc = tRC;
- prio = (j + 1) % nbk;
+ RRDc = m_config->tRRD;
+ bk[j]->RCDc = m_config->tRCD;
+ bk[j]->RCDWRc = m_config->tRCDWR;
+ bk[j]->RASc = m_config->tRAS;
+ bk[j]->RCc = m_config->tRC;
+ prio = (j + 1) % m_config->nbk;
issued = 1;
n_act_partial++;
n_act++;
@@ -362,8 +353,8 @@ void dram_t::issueCMD()
(!bk[j]->RASc) ) {
// make the bank idle again
bk[j]->state = BANK_IDLE;
- bk[j]->RPc = tRP;
- prio = (j + 1) % nbk;
+ bk[j]->RPc = m_config->tRP;
+ prio = (j + 1) % m_config->nbk;
issued = 1;
n_pre++;
n_pre_partial++;
@@ -397,7 +388,7 @@ void dram_t::issueCMD()
DEC2ZERO(CCDc);
DEC2ZERO(RTWc);
DEC2ZERO(WTRc);
- for (j=0;j<nbk;j++) {
+ for (j=0;j<m_config->nbk;j++) {
DEC2ZERO(bk[j]->RCDc);
DEC2ZERO(bk[j]->RASc);
DEC2ZERO(bk[j]->RCc);
@@ -420,7 +411,7 @@ class mem_fetch* dram_t::pop()
printf("\tDQ: BK%d Row:%03x Col:%03x",
mrq->bk, mrq->row, mrq->col + mrq->dqbytes);
#endif
- mrq->dqbytes += BL * busW * gpu_n_mem_per_ctrlr; /*16 bytes*/
+ mrq->dqbytes += m_config->BL * m_config->busW * m_config->gpu_n_mem_per_ctrlr; /*16 bytes*/
if (mrq->dqbytes >= mrq->nbytes) {
if (m_config->gpgpu_memlatency_stat) {
unsigned dq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - mrq->timestamp;
@@ -457,15 +448,15 @@ void dram_t::print( FILE* simFile) const
{
unsigned i;
fprintf(simFile,"DRAM[%d]: %d bks, busW=%d BL=%d CL=%d, ",
- id, nbk, busW, BL, CL );
+ 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",
- tCCD, tRRD, tRCD, tRAS, tRP, tRC );
+ m_config->tCCD, m_config->tRRD, 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_req=%d n_rd=%d n_write=%d bw_util=%.4g\n",
n_cmd, n_nop, n_act, n_pre, n_req, n_rd, n_wr,
(float)bwutil/n_cmd);
fprintf(simFile,"n_activity=%d dram_eff=%.4g\n",
n_activity, (float)bwutil/n_activity);
- for (i=0;i<nbk;i++) {
+ for (i=0;i<m_config->nbk;i++) {
fprintf(simFile, "bk%d: %da %di ",i,bk[i]->n_access,bk[i]->n_idle);
}
fprintf(simFile, "\n");
@@ -481,7 +472,7 @@ void dram_t::visualize() const
{
printf("RRDc=%d CCDc=%d mrqq.Length=%d rwq.Length=%d\n",
RRDc, CCDc, mrqq->get_length(),rwq->get_length());
- for (unsigned i=0;i<nbk;i++) {
+ for (unsigned i=0;i<m_config->nbk;i++) {
printf("BK%d: state=%c curr_row=%03x, %2d %2d %2d %2d %p ",
i, bk[i]->state, bk[i]->curr_row,
bk[i]->RCDc, bk[i]->RASc,
@@ -547,7 +538,7 @@ void dram_t::visualizer_print( gzFile visualizer_file )
n_req_partial = 0;
// dram access type classification
- for (unsigned j = 0; j < m_config->gpu_mem_n_bk; j++) {
+ for (unsigned j = 0; j < m_config->nbk; j++) {
gzprintf(visualizer_file,"dramglobal_acc_r: %u %u %u\n", id, j,
m_stats->mem_access_type_stats[GLOBAL_ACC_R][id][j]);
gzprintf(visualizer_file,"dramglobal_acc_w: %u %u %u\n", id, j,
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index 5428533..cf9f68d 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -123,9 +123,7 @@ struct mem_fetch;
class dram_t
{
public:
- dram_t( unsigned int parition_id, struct memory_config *config);
-
- void set_stats( class memory_stats_t *stats ) {m_stats=stats;}
+ dram_t( unsigned int parition_id, const struct memory_config *config, class memory_stats_t *stats );
int full();
void print( FILE* simFile ) const;
@@ -152,24 +150,8 @@ private:
void scheduler_fifo();
void fast_scheduler_ideal();
- struct memory_config *m_config;
-
- unsigned int tCCD; //column to column delay
- unsigned int tRRD; //minimal time required between activation of rows in different banks
- unsigned int tRCD; //row to column delay - time required to activate a row before a read
- unsigned int tRCDWR;//row to column delay for a write command
- unsigned int tRAS; //time needed to activate row
- unsigned int tRP; //row precharge ie. deactivate row
- unsigned int tRC; //row cycle time ie. precharge current, then activate different row
-
- unsigned int CL; //CAS latency
- unsigned int WL; //WRITE latency
- unsigned int BL; //Burst Length in bytes (we're using 4? could be 8)
- unsigned int tRTW; //time to switch from read to write
- unsigned int tWTR; //time to switch from write to read 5? look in datasheet
- unsigned int busW;
+ const struct memory_config *m_config;
- unsigned int nbk;
bank_t **bk;
unsigned int prio;
diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc
index 1e36b05..110894f 100644
--- a/src/gpgpu-sim/dram_sched.cc
+++ b/src/gpgpu-sim/dram_sched.cc
@@ -70,17 +70,18 @@
#include "../abstract_hardware_model.h"
#include "mem_latency_stat.h"
-ideal_dram_scheduler::ideal_dram_scheduler( dram_t *dm )
+ideal_dram_scheduler::ideal_dram_scheduler( const memory_config *config, dram_t *dm, memory_stats_t *stats )
{
-
+ m_config = config;
+ m_stats = stats;
m_num_pending = 0;
m_dram = dm;
- m_queue = new std::list<dram_req_t*>[dm->nbk];
- m_bins = new std::map<unsigned,std::list<std::list<dram_req_t*>::iterator> >[ dm->nbk ];
- m_last_row = new std::list<std::list<dram_req_t*>::iterator>*[ dm->nbk ];
- curr_row_service_time = new unsigned[dm->nbk];
- row_service_timestamp = new unsigned[dm->nbk];
- for ( unsigned i=0; i < dm->nbk; i++ ) {
+ m_queue = new std::list<dram_req_t*>[m_config->nbk];
+ m_bins = new std::map<unsigned,std::list<std::list<dram_req_t*>::iterator> >[ m_config->nbk ];
+ m_last_row = new std::list<std::list<dram_req_t*>::iterator>*[ m_config->nbk ];
+ curr_row_service_time = new unsigned[m_config->nbk];
+ row_service_timestamp = new unsigned[m_config->nbk];
+ for ( unsigned i=0; i < m_config->nbk; i++ ) {
m_queue[i].clear();
m_bins[i].clear();
m_last_row[i] = NULL;
@@ -107,16 +108,16 @@ inline void ideal_dram_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 (curr_row_service_time[bank] > max_servicetime2samerow[m_dram->id][bank])
- max_servicetime2samerow[m_dram->id][bank] = curr_row_service_time[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;
- if (concurrent_row_access[m_dram->id][bank] > max_conc_access2samerow[m_dram->id][bank]) {
- max_conc_access2samerow[m_dram->id][bank] = concurrent_row_access[m_dram->id][bank];
+ 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];
}
- concurrent_row_access[m_dram->id][bank] = 0;
- num_activates[m_dram->id][bank]++;
+ m_stats->concurrent_row_access[m_dram->id][bank] = 0;
+ m_stats->num_activates[m_dram->id][bank]++;
}
dram_req_t *ideal_dram_scheduler::schedule( unsigned bank, unsigned curr_row )
@@ -142,8 +143,8 @@ dram_req_t *ideal_dram_scheduler::schedule( unsigned bank, unsigned curr_row )
std::list<dram_req_t*>::iterator next = m_last_row[bank]->back();
dram_req_t *req = (*next);
- concurrent_row_access[m_dram->id][bank]++;
- row_access[m_dram->id][bank]++;
+ m_stats->concurrent_row_access[m_dram->id][bank]++;
+ m_stats->row_access[m_dram->id][bank]++;
m_last_row[bank]->pop_back();
m_queue[bank].erase(next);
@@ -165,35 +166,34 @@ dram_req_t *ideal_dram_scheduler::schedule( unsigned bank, unsigned curr_row )
void ideal_dram_scheduler::print( FILE *fp )
{
- for ( unsigned b=0; b < m_dram->nbk; b++ ) {
+ for ( unsigned b=0; b < m_config->nbk; b++ ) {
printf(" %u: queue length = %u\n", b, (unsigned)m_queue[b].size() );
}
}
void dram_t::fast_scheduler_ideal()
{
- dram_t* dm=this;
unsigned mrq_latency;
- ideal_dram_scheduler *sched = dm->m_fast_ideal_scheduler;
- while ( !dm->mrqq->empty() && (!m_config->gpgpu_dram_sched_queue_size || sched->num_pending() < m_config->gpgpu_dram_sched_queue_size)) {
- dram_req_t *req = dm->mrqq->pop(gpu_sim_cycle);
+ ideal_dram_scheduler *sched = m_fast_ideal_scheduler;
+ while ( !mrqq->empty() && (!m_config->gpgpu_dram_sched_queue_size || sched->num_pending() < m_config->gpgpu_dram_sched_queue_size)) {
+ dram_req_t *req = mrqq->pop(gpu_sim_cycle);
sched->add_req(req);
}
dram_req_t *req;
unsigned i;
- for ( i=0; i < dm->nbk; i++ ) {
- unsigned b = (i+dm->prio)%dm->nbk;
- if ( !dm->bk[b]->mrq ) {
+ for ( i=0; i < m_config->nbk; i++ ) {
+ unsigned b = (i+prio)%m_config->nbk;
+ if ( !bk[b]->mrq ) {
- req = sched->schedule(b, dm->bk[b]->curr_row);
+ req = sched->schedule(b, bk[b]->curr_row);
if ( req ) {
- dm->prio = (dm->prio+1)%dm->nbk;
- dm->bk[b]->mrq = req;
+ 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 - dm->bk[b]->mrq->timestamp;
- dm->bk[b]->mrq->timestamp = gpu_tot_sim_cycle + gpu_sim_cycle;
+ mrq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - bk[b]->mrq->timestamp;
+ bk[b]->mrq->timestamp = gpu_tot_sim_cycle + 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/dram_sched.h b/src/gpgpu-sim/dram_sched.h
index 49cae22..eaad744 100644
--- a/src/gpgpu-sim/dram_sched.h
+++ b/src/gpgpu-sim/dram_sched.h
@@ -76,7 +76,7 @@
class ideal_dram_scheduler {
public:
- ideal_dram_scheduler( dram_t *dm );
+ ideal_dram_scheduler( const memory_config *config, dram_t *dm, memory_stats_t *stats );
void add_req( dram_req_t *req );
std::list<dram_req_t*>::iterator binarysort_VFTF(dram_req_t *req);
std::list<dram_req_t*>::iterator sort_VFTF(dram_req_t *req);
@@ -86,7 +86,7 @@ public:
unsigned num_pending() const { return m_num_pending;}
private:
-
+ const memory_config *m_config;
dram_t *m_dram;
unsigned m_num_pending;
std::list<dram_req_t*> *m_queue;
@@ -94,6 +94,8 @@ private:
std::list<std::list<dram_req_t*>::iterator> **m_last_row;
unsigned *curr_row_service_time; //one set of variables for each bank.
unsigned *row_service_timestamp; //tracks when scheduler began servicing current row
+
+ memory_stats_t *m_stats;
};
#endif
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 6f2bbca..faa817f 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -79,7 +79,6 @@ cache_t::~cache_t()
cache_t::cache_t( const char *name,
const char *opt,
- unsigned long long int bank_mask,
enum cache_write_policy wp,
int core_id,
int type_id)
@@ -95,74 +94,54 @@ cache_t::cache_t( const char *name,
}
assert(nset && assoc);
- cache_t *cp = this;
unsigned int nlines;
- unsigned int i;
-
-
nlines = nset * assoc;
- cp->bank_mask = bank_mask;
- cp->m_name = (char*) malloc(sizeof(char) * (strlen(name) + 1));
- strcpy(cp->m_name, name);
- cp->m_nset = nset;
- cp->m_nset_log2 = LOGB2(nset);
- cp->m_assoc = assoc;
- cp->m_line_sz = line_sz;
- cp->line_sz_log2 = LOGB2(line_sz);
- cp->policy = policy;
- cp->m_lines = (cache_block_t*) calloc(nlines, sizeof(cache_block_t));
- cp->write_policy = wp;
-
- for (i=0; i<nlines; i++) {
- cp->m_lines[i].line_sz = line_sz;
- cp->m_lines[i].status = 0;
- }
+ m_name = name;
+ m_nset = nset;
+ m_nset_log2 = LOGB2(nset);
+ m_assoc = assoc;
+ m_line_sz = line_sz;
+ m_line_sz_log2 = LOGB2(line_sz);
+ m_replacement_policy = policy;
+ m_write_policy = wp;
+ m_lines = new cache_block_t[nlines];
// don't hook up with any logger
- cp->core_id = -1;
- cp->type_id = -1;
+ m_core_id = -1;
+ m_type_id = -1;
// initialize snapshot counters for visualizer
- cp->prev_snapshot_access = 0;
- cp->prev_snapshot_miss = 0;
- cp->prev_snapshot_merge_hit = 0;
- cp->core_id = core_id;
- cp->type_id = type_id;
+ m_prev_snapshot_access = 0;
+ m_prev_snapshot_miss = 0;
+ m_prev_snapshot_merge_hit = 0;
+ m_core_id = core_id;
+ m_type_id = type_id;
}
-enum cache_request_status cache_t::access( unsigned long long int addr,
- unsigned char write,
- unsigned int sim_cycle,
- address_type *wb_address )
+enum cache_request_status cache_t::access( new_addr_type addr, bool write, unsigned int cycle, address_type *wb_address )
{
- cache_t *cp = this;
- unsigned long long int bank_addr; // offset within bank
bool all_reserved = true;
cache_block_t *pending_line = NULL;
cache_block_t *clean_line = NULL;
+ new_addr_type bank_addr = addr; // offset within bank
- if (cp->bank_mask)
- bank_addr = addrdec_packbits(cp->bank_mask, addr, 64, 0);
- else
- bank_addr = addr;
-
- unsigned set = (bank_addr >> cp->line_sz_log2) & ( (1<<cp->m_nset_log2) - 1 );
- unsigned long long tag = bank_addr >> (cp->line_sz_log2 + cp->m_nset_log2);
+ unsigned set = (bank_addr >> m_line_sz_log2) & ( (1<<m_nset_log2) - 1 );
+ unsigned long long tag = bank_addr >> (m_line_sz_log2 + m_nset_log2);
- cp->m_access++;
- shader_cache_access_log(cp->core_id, cp->type_id, 0);
+ m_access++;
+ shader_cache_access_log(m_core_id, m_type_id, 0);
- for (unsigned way=0; way<cp->m_assoc; way++) {
- cache_block_t *line = &(cp->m_lines[set*cp->m_assoc+way] );
+ for (unsigned way=0; way<m_assoc; way++) {
+ cache_block_t *line = &(m_lines[set*m_assoc+way] );
if (line->tag == tag) {
if (line->status & RESERVED) {
pending_line = line;
break;
} else if (line->status & VALID) {
- line->last_used = sim_cycle;
+ line->last_used = cycle;
if (write)
line->status |= DIRTY;
- if (cp->write_policy == write_through)
+ if (m_write_policy == write_through)
return HIT_W_WT;
return HIT;
}
@@ -173,10 +152,10 @@ enum cache_request_status cache_t::access( unsigned long long int addr,
clean_line = line;
}
}
- cp->miss++;
- shader_cache_access_log(cp->core_id, cp->type_id, 1);
+ m_miss++;
+ shader_cache_access_log(m_core_id, m_type_id, 1);
- if (pending_line || cp->write_policy != write_back || write) {
+ if (pending_line || m_write_policy != write_back || write) {
if (pending_line) {
if( write ) // write hit-under-miss (irrelevant whether write-back or write-through)
// - timing assumes a large enough write buffer in shader core that we never
@@ -189,7 +168,7 @@ enum cache_request_status cache_t::access( unsigned long long int addr,
}
// at this point: this must be a write back cache (and not a hit-under-miss)
- assert( cp->write_policy == write_back );
+ assert( m_write_policy == write_back );
if (all_reserved)
// cannot service this request, because we can't garantee that we have room for the line when it comes back
@@ -205,14 +184,14 @@ enum cache_request_status cache_t::access( unsigned long long int addr,
// no clean lines, need to kick a line out to reserve a spot
cache_block_t *wb_line = NULL;
- for (unsigned way=0; way<cp->m_assoc; way++) {
- cache_block_t *line = &(cp->m_lines[set*cp->m_assoc+way] );
+ for (unsigned way=0; way<m_assoc; way++) {
+ cache_block_t *line = &(m_lines[set*m_assoc+way] );
if (line->status & VALID && !(line->status & RESERVED)) {
if (!wb_line) {
wb_line = line;
continue;
}
- switch (cp->policy) {
+ switch (m_replacement_policy) {
case LRU:
if (line->last_used < wb_line->last_used)
wb_line = line;
@@ -238,12 +217,12 @@ enum cache_request_status cache_t::access( unsigned long long int addr,
}
// Obtain the windowed cache miss rate for visualizer
-float cache_t::shd_cache_windowed_cache_miss_rate( int minus_merge_hit )
+float cache_t::windowed_cache_miss_rate( int minus_merge_hit )
{
cache_t *cp = this;
- unsigned int n_access = cp->m_access - cp->prev_snapshot_access;
- unsigned int n_miss = cp->miss - cp->prev_snapshot_miss;
- unsigned int n_merge_hit = cp->merge_hit - cp->prev_snapshot_merge_hit;
+ unsigned int n_access = cp->m_access - cp->m_prev_snapshot_access;
+ unsigned int n_miss = cp->m_miss - cp->m_prev_snapshot_miss;
+ unsigned int n_merge_hit = cp->m_merge_hit - cp->m_prev_snapshot_merge_hit;
if (minus_merge_hit)
n_miss -= n_merge_hit;
@@ -255,38 +234,30 @@ float cache_t::shd_cache_windowed_cache_miss_rate( int minus_merge_hit )
}
// start a new sampling window
-void cache_t::shd_cache_new_window()
+void cache_t::new_window()
{
- cache_t *cp = this;
- cp->prev_snapshot_access = cp->m_access;
- cp->prev_snapshot_miss = cp->miss;
- cp->prev_snapshot_merge_hit = cp->merge_hit;
+ m_prev_snapshot_access = m_access;
+ m_prev_snapshot_miss = m_miss;
+ m_prev_snapshot_merge_hit = m_merge_hit;
}
-static unsigned int _n_line_existed = 0; // debug counter
-
// Fetch requested data into cache line.
// Returning address on the replaced line if it is dirty, or -1 if it is clean
// Assume the line is filled all at once.
-new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycle )
+new_addr_type cache_t::fill( new_addr_type addr, unsigned int sim_cycle )
{
- cache_t *cp = this;
unsigned int base = 0 ;
- unsigned int maxway = cp->m_assoc ;
+ unsigned int maxway = m_assoc;
cache_block_t *pline, *cline;
- unsigned long long int packed_addr;
- if (cp->bank_mask)
- packed_addr = addrdec_packbits(cp->bank_mask, addr, 64, 0);
- else
- packed_addr = addr;
- unsigned set = (packed_addr >> cp->line_sz_log2) & ( (1<<cp->m_nset_log2) - 1 );
- unsigned long long tag = packed_addr >> (cp->line_sz_log2 + cp->m_nset_log2);
+ new_addr_type packed_addr = addr;
+ unsigned set = (packed_addr >> m_line_sz_log2) & ( (1<<m_nset_log2) - 1 );
+ unsigned long long tag = packed_addr >> (m_line_sz_log2 + m_nset_log2);
- if (cp->write_policy == write_back) {
+ if (m_write_policy == write_back) {
//this request must have a reserved spot
cline = NULL;
for (unsigned i=base; i<maxway; i++) {
- pline = &(cp->m_lines[set*cp->m_assoc+i] );
+ pline = &(m_lines[set*m_assoc+i] );
if ((pline->tag == tag) && (pline->status & RESERVED)) {
cline = pline;
break;
@@ -294,8 +265,6 @@ new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycl
if ((pline->tag == tag) && (pline->status & VALID)) {
//A second fill has returned to a line in the cache
//discard it as line in cache may have been modified, or is the same
- _n_line_existed++;
-
return -1;
}
}
@@ -323,7 +292,7 @@ new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycl
bool nofreeslot = true;
bool line_exists = false;
for (unsigned i=base; i<maxway; i++) {
- pline = &(cp->m_lines[set*cp->m_assoc+i] );
+ pline = &(m_lines[set*m_assoc+i] );
if (!(pline->status & VALID)) {
cline = pline;
nofreeslot = false;
@@ -336,16 +305,15 @@ new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycl
}
if (line_exists) {
- _n_line_existed += 1;
return -1; // don't need to spill any line, nor it needs to be filled
}
if (nofreeslot) {
- cline = &(cp->m_lines[set*cp->m_assoc+base] );
+ cline = &(m_lines[set*m_assoc+base] );
for (unsigned i=1+base; i<maxway; i++) {
- pline = &(cp->m_lines[set*cp->m_assoc+i] );
+ pline = &(m_lines[set*m_assoc+i] );
if (pline->status & VALID) {
- switch (cp->policy) {
+ switch (m_replacement_policy) {
case LRU:
if (pline->last_used < cline->last_used)
cline = pline;
@@ -382,28 +350,26 @@ new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycl
unsigned int cache_t::flush()
{
- cache_t *cp = this;
int dirty_lines_flushed = 0 ;
- for (unsigned i = 0; i < cp->m_nset * cp->m_assoc ; i++) {
- if ( (cp->m_lines[i].status & (DIRTY|VALID)) == (DIRTY|VALID) ) {
+ for (unsigned i = 0; i < m_nset * m_assoc ; i++) {
+ if ( (m_lines[i].status & (DIRTY|VALID)) == (DIRTY|VALID) ) {
dirty_lines_flushed++;
}
- cp->m_lines[i].status &= ~VALID;
- cp->m_lines[i].status &= ~DIRTY;
+ m_lines[i].status &= ~VALID;
+ m_lines[i].status &= ~DIRTY;
}
return dirty_lines_flushed;
}
-void cache_t::shd_cache_print( FILE *stream, unsigned &total_access, unsigned &total_misses )
+void cache_t::print( FILE *stream, unsigned &total_access, unsigned &total_misses )
{
- cache_t *cp = this;
- fprintf( stream, "Cache %s:\t", cp->m_name);
+ fprintf( stream, "Cache %s:\t", m_name.c_str() );
fprintf( stream, "Size = %d B (%d Set x %d-way x %d byte line)\n",
- cp->m_line_sz * cp->m_nset * cp->m_assoc,
- cp->m_nset, cp->m_assoc, cp->m_line_sz );
+ m_line_sz * m_nset * m_assoc,
+ m_nset, m_assoc, m_line_sz );
fprintf( stream, "\t\tAccess = %d, Miss = %d (%.3g), -MgHts = %d (%.3g)\n",
- cp->m_access, cp->miss, (float) cp->miss / cp->m_access,
- cp->miss - cp->merge_hit, (float) (cp->miss - cp->merge_hit) / cp->m_access);
- total_misses+=cp->miss;
- total_access+=cp->m_access;
+ m_access, m_miss, (float) m_miss / m_access,
+ m_miss - m_merge_hit, (float) (m_miss - m_merge_hit) / m_access);
+ total_misses+=m_miss;
+ total_access+=m_access;
}
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 617307c..ff071e0 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -86,12 +86,18 @@ enum cache_request_status {
};
struct cache_block_t {
- unsigned long long int tag;
- unsigned long long int addr;
- unsigned int set;
- unsigned int line_sz; /* bytes */
- unsigned int fetch_time;
- unsigned int last_used;
+ cache_block_t()
+ {
+ tag=0;
+ addr=0;
+ fetch_time=0;
+ last_used=0;
+ status=0;
+ }
+ new_addr_type tag;
+ new_addr_type addr;
+ unsigned fetch_time;
+ unsigned last_used;
unsigned char status; /* valid, dirty... etc */
};
@@ -99,7 +105,7 @@ struct cache_block_t {
#define FIFO 'F'
#define RANDOM 'R'
-enum cache_write_policy{
+enum cache_write_policy {
no_writes, //line replacement when new line arrives
write_back, //line replacement when new line arrives
write_through //reservation based, use much handle reservation full error.
@@ -109,51 +115,50 @@ class cache_t {
public:
cache_t( const char *name,
const char *opt,
- unsigned long long int bank_mask,
enum cache_write_policy wp,
int core_id,
int type_id);
~cache_t();
enum cache_request_status access( new_addr_type addr,
- unsigned char write,
+ bool write,
unsigned int sim_cycle,
- address_type *wb_address);
+ address_type *wb_address );
- new_addr_type shd_cache_fill( new_addr_type addr, unsigned int sim_cycle );
+ new_addr_type fill( new_addr_type addr, unsigned int sim_cycle );
unsigned flush();
- void shd_cache_print( FILE *stream, unsigned &total_access, unsigned &total_misses );
- float shd_cache_windowed_cache_miss_rate(int);
- void shd_cache_new_window();
+ void print( FILE *stream, unsigned &total_access, unsigned &total_misses );
+ float windowed_cache_miss_rate(int);
+ void new_window();
unsigned get_line_sz() const { return m_line_sz; }
private:
- char *m_name;
+ std::string m_name;
- cache_block_t *m_lines; /* nset x assoc lines in total */
- unsigned int m_nset;
- unsigned int m_nset_log2;
- unsigned int m_assoc;
- unsigned int m_line_sz; // bytes
- unsigned int line_sz_log2;
- enum cache_write_policy write_policy;
- unsigned char policy;
+ cache_block_t *m_lines; /* nbanks x nset x assoc lines in total */
+ unsigned m_n_banks;
+ unsigned m_nset;
+ unsigned m_nset_log2;
+ unsigned m_assoc;
+ unsigned m_line_sz; // bytes
+ unsigned m_line_sz_log2;
- unsigned int m_access;
- unsigned int miss;
- unsigned int merge_hit; // number of cache miss that hit the same line (and merged as a result)
+ enum cache_write_policy m_write_policy;
+ unsigned char m_replacement_policy;
+
+ unsigned m_access;
+ unsigned m_miss;
+ unsigned m_merge_hit; // number of cache miss that hit the same line (and merged as a result)
// performance counters for calculating the amount of misses within a time window
- unsigned int prev_snapshot_access;
- unsigned int prev_snapshot_miss;
- unsigned int prev_snapshot_merge_hit;
+ unsigned m_prev_snapshot_access;
+ unsigned m_prev_snapshot_miss;
+ unsigned m_prev_snapshot_merge_hit;
- int core_id; // which shader core is using this
- int type_id; // what kind of cache is this (normal, texture, constant)
-
- unsigned long long int bank_mask;
+ int m_core_id; // which shader core is using this
+ int m_type_id; // what kind of cache is this (normal, texture, constant)
class linear_histogram_logger *m_logger;
};
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 4e434c4..06a4c15 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -106,20 +106,9 @@
bool g_interactive_debugger_enabled=false;
-unsigned made_read_mfs = 0;
-unsigned made_write_mfs = 0;
-unsigned freed_read_mfs = 0;
-unsigned freed_L1write_mfs = 0;
-unsigned freed_L2write_mfs = 0;
-unsigned freed_dummy_read_mfs = 0;
unsigned long long gpu_sim_cycle = 0;
unsigned long long gpu_tot_sim_cycle = 0;
-unsigned int **concurrent_row_access; //concurrent_row_access[dram chip id][bank id]
-unsigned int **num_activates; //num_activates[dram chip id][bank id]
-unsigned int **row_access; //row_access[dram chip id][bank id]
-unsigned int **max_conc_access2samerow; //max_conc_access2samerow[dram chip id][bank id]
-unsigned int **max_servicetime2samerow; //max_servicetime2samerow[dram chip id][bank id]
unsigned int gpgpu_n_sent_writes = 0;
unsigned int gpgpu_n_processed_writes = 0;
@@ -149,9 +138,12 @@ int gpgpu_dram_sched_queue_size;
bool gpgpu_flush_cache;
int gpgpu_mem_address_mask;
int gpgpu_cflog_interval;
+char * gpgpu_clock_domains;
+int g_ptx_inst_debug_to_file;
+char* g_ptx_inst_debug_file;
+int g_ptx_inst_debug_thread_uid;
-/* Defining Clock Domains
-basically just the ratio is important */
+/* Clock Domains */
#define CORE 0x01
#define L2 0x02
@@ -159,20 +151,9 @@ basically just the ratio is important */
#define ICNT 0x08
-char * gpgpu_clock_domains;
-
-/* GPU uArch parameters */
-unsigned int gpu_n_mem_per_ctrlr;
-char *gpgpu_dwf_hw_opt;
-unsigned int more_thread = 1;
-
#define MEM_LATENCY_STAT_IMPL
#include "mem_latency_stat.h"
-int g_ptx_inst_debug_to_file;
-char* g_ptx_inst_debug_file;
-int g_ptx_inst_debug_thread_uid;
-
void visualizer_options(option_parser_t opp);
void gpgpu_sim::reg_options(option_parser_t opp)
@@ -246,7 +227,7 @@ void gpgpu_sim::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_n_mem", OPT_UINT32, &m_memory_config->m_n_mem,
"number of memory modules (e.g. memory controllers) in gpu",
"8");
- option_parser_register(opp, "-gpgpu_n_mem_per_ctrlr", OPT_UINT32, &gpu_n_mem_per_ctrlr,
+ option_parser_register(opp, "-gpgpu_n_mem_per_ctrlr", OPT_UINT32, &m_memory_config->gpu_n_mem_per_ctrlr,
"number of memory chips per memory controller",
"1");
option_parser_register(opp, "-gpgpu_runtime_stat", OPT_CSTR, &gpgpu_runtime_stat,
@@ -269,11 +250,11 @@ void gpgpu_sim::reg_options(option_parser_t opp)
"0 = unlimited (default); # entries per chip",
"0");
- option_parser_register(opp, "-gpgpu_dram_buswidth", OPT_UINT32, &m_memory_config->gpgpu_dram_buswidth,
+ option_parser_register(opp, "-gpgpu_dram_buswidth", OPT_UINT32, &m_memory_config->busW,
"default = 4 bytes (8 bytes per cycle at DDR)",
"4");
- option_parser_register(opp, "-gpgpu_dram_burst_length", OPT_UINT32, &m_memory_config->gpgpu_dram_burst_length,
+ option_parser_register(opp, "-gpgpu_dram_burst_length", OPT_UINT32, &m_memory_config->BL,
"Burst length of each DRAM request (default = 4 DDR cycle)",
"4");
@@ -390,7 +371,7 @@ void gpgpu_sim::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &m_shader_config->gpgpu_coalesce_arch,
"Coalescing arch (default = 13, anything else is off for now)",
"13");
- addrdec_setoption(opp);
+ m_memory_config->m_address_mapping.addrdec_setoption(opp);
L2c_options(opp);
visualizer_options(opp);
ptx_file_line_stats_options(opp);
@@ -483,33 +464,16 @@ void gpgpu_sim::init_gpu()
m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters];
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
- m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_shader_stats);
+ m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_memory_config,m_shader_stats);
ptx_file_line_stats_create_exposed_latency_tracker(num_shader());
- addrdec_setnchip(m_memory_config->m_n_mem);
+ m_memory_stats = new memory_stats_t(num_shader(),m_shader_config,m_memory_config);
+
+ m_memory_config->init();
m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem];
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 = new memory_stats_t(m_memory_config->m_n_mem,num_shader(),m_shader_config,m_memory_config);
- for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
- m_memory_partition_unit[i]->set_stats(m_memory_stats);
-
- concurrent_row_access = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
- num_activates = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
- row_access = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
- max_conc_access2samerow = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
- max_servicetime2samerow = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
-
- for (unsigned i=0;i<m_memory_config->m_n_mem ;i++ ) {
- concurrent_row_access[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
- row_access[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
- num_activates[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
- max_conc_access2samerow[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
- max_servicetime2samerow[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
- }
-
- m_memory_stats = new memory_stats_t(m_memory_config->m_n_mem,num_shader(),m_shader_config,m_memory_config);
+ m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats);
icnt_init(m_shader_config->n_simt_clusters, m_memory_config->m_n_mem,m_shader_config);
@@ -754,7 +718,7 @@ void gpgpu_sim::gpu_print_stat() const
// performance counter that are not local to one shader
shader_print_accstats(stdout);
- m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->gpu_mem_n_bk);
+ m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->nbk);
// merge misses
printf("L1 read misses = %d\n", m_shader_stats->L1_read_miss);
printf("L1 write misses = %d\n", m_shader_stats->L1_write_miss);
@@ -763,12 +727,6 @@ void gpgpu_sim::gpu_print_stat() const
printf("L1 texture misses = %d\n", m_shader_stats->L1_texture_miss);
printf("L1 const misses = %d\n", m_shader_stats->L1_const_miss);
m_memory_stats->print(stdout);
- printf("made_read_mfs = %d\n", made_read_mfs);
- printf("made_write_mfs = %d\n", made_write_mfs);
- printf("freed_read_mfs = %d\n", freed_read_mfs);
- printf("freed_L1write_mfs = %d\n", freed_L1write_mfs);
- printf("freed_L2write_mfs = %d\n", freed_L2write_mfs);
- printf("freed_dummy_read_mfs = %d\n", freed_dummy_read_mfs);
printf("gpgpu_n_mem_read_local = %d\n", m_shader_stats->gpgpu_n_mem_read_local);
printf("gpgpu_n_mem_write_local = %d\n", m_shader_stats->gpgpu_n_mem_write_local);
@@ -1138,7 +1096,6 @@ void gpgpu_sim::cycle()
if (!mf->get_is_write())
mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle);
else {
- freed_L1write_mfs++;
gpgpu_n_processed_writes++;
}
::icnt_push( m_shader_config->mem2device(i), mf->get_tpc(), mf, response_size );
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 51ebd58..0ba1bb8 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -70,6 +70,8 @@
#define GPU_SIM_H
#include "../abstract_hardware_model.h"
+#include "addrdec.h"
+
#include <list>
#include <stdio.h>
@@ -102,23 +104,55 @@ enum dram_ctrl_t {
};
struct memory_config {
+ memory_config()
+ {
+ gpgpu_cache_dl2_opt=NULL;
+ gpgpu_dram_timing_opt=NULL;
+ gpgpu_L2_queue_config=NULL;
+ }
+ void init()
+ {
+ assert(gpgpu_dram_timing_opt);
+ sscanf(gpgpu_dram_timing_opt,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",&nbk,&tCCD,&tRRD,&tRCD,&tRAS,&tRP,&tRC,&CL,&WL,&tWTR);
+ tRCDWR = tRCD-(WL+1);
+ tRTW = (CL+(BL/2)+2-WL);
+ m_address_mapping.init(m_n_mem);
+ }
+
char *gpgpu_cache_dl2_opt;
char *gpgpu_dram_timing_opt;
char *gpgpu_L2_queue_config;
bool gpgpu_l2_readoverwrite;
bool l2_ideal;
unsigned gpgpu_dram_sched_queue_size;
- unsigned int gpu_mem_n_bk;
enum dram_ctrl_t scheduler_type;
bool gpgpu_memlatency_stat;
- unsigned gpgpu_dram_buswidth;
- unsigned gpgpu_dram_burst_length;
unsigned m_n_mem;
+ unsigned int gpu_n_mem_per_ctrlr;
+
+ // DRAM parameters
+ unsigned int tCCD; //column to column delay
+ unsigned int tRRD; //minimal time required between activation of rows in different banks
+ unsigned int tRCD; //row to column delay - time required to activate a row before a read
+ unsigned int tRCDWR; //row to column delay for a write command
+ unsigned int tRAS; //time needed to activate row
+ unsigned int tRP; //row precharge ie. deactivate row
+ unsigned int tRC; //row cycle time ie. precharge current, then activate different row
+
+ unsigned int CL; //CAS latency
+ unsigned int WL; //WRITE latency
+ unsigned int BL; //Burst Length in bytes (we're using 4? could be 8)
+ unsigned int tRTW; //time to switch from read to write
+ unsigned int tWTR; //time to switch from write to read 5? look in datasheet
+ unsigned int busW;
+
+ unsigned int nbk;
+
+ linear_to_raw_address_translation m_address_mapping;
};
// global config
extern int gpgpu_mem_address_mask;
-extern unsigned int gpu_n_mem_per_ctrlr;
extern int gpu_runtime_stat_flag;
extern int gpgpu_cflog_interval;
@@ -194,6 +228,8 @@ private:
kernel_info_t m_the_kernel;
std::list<kernel_info_t> m_running_kernels;
+ unsigned int more_thread;
+
// time of next rising edge
double core_time;
double icnt_time;
@@ -251,12 +287,6 @@ extern unsigned g_next_mf_request_uid;
// stats
-extern unsigned int **max_conc_access2samerow;
-extern unsigned int **max_servicetime2samerow;
-extern unsigned int **row_access;
-extern unsigned int **num_activates;
-extern unsigned int **concurrent_row_access; //concurrent_row_access[dram chip id][bank id]
-
extern unsigned int gpgpu_n_sent_writes;
extern unsigned int gpgpu_n_processed_writes;
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 29903ea..47ead65 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -85,12 +85,6 @@
template class fifo_pipeline<mem_fetch>;
-// external dependencies
-extern unsigned long long int addrdec_mask[5];
-extern unsigned made_write_mfs;
-extern unsigned freed_L1write_mfs;
-extern unsigned freed_L2write_mfs;
-
address_type L2c_mshr::cache_tag(const mem_fetch *mf) const
{
return (mf->get_addr() & ~(m_linesize - 1));
@@ -287,12 +281,6 @@ memory_partition_unit::~memory_partition_unit()
delete m_accessLocality;
}
-void memory_partition_unit::set_stats( class memory_stats_t *stats )
-{
- m_stats=stats;
- m_dram->set_stats(stats);
-}
-
void memory_partition_unit::cache_cycle()
{
process_dram_output(); // pop from dram
@@ -322,17 +310,19 @@ bool memory_partition_unit::full() const
// L2 access functions
// L2 Cache Creation
-memory_partition_unit::memory_partition_unit( unsigned partition_id, struct memory_config *config )
+memory_partition_unit::memory_partition_unit( unsigned partition_id,
+ struct memory_config *config,
+ class memory_stats_t *stats )
{
m_id = partition_id;
m_config=config;
- m_stats=NULL;
- m_dram = new dram_t(m_id, m_config);
+ m_stats=stats;
+ m_dram = new dram_t(m_id,m_config,m_stats);
if( m_config->gpgpu_cache_dl2_opt ) {
char L2c_name[32];
snprintf(L2c_name, 32, "L2_%03d", m_id);
- m_L2cache = new cache_t(L2c_name,m_config->gpgpu_cache_dl2_opt, ~addrdec_mask[CHIP], write_through, -1, -1 );
+ m_L2cache = new cache_t(L2c_name,m_config->gpgpu_cache_dl2_opt, write_through,-1,-1);
m_mshr = new L2c_mshr(m_L2cache->get_line_sz());
m_missTracker = new L2c_miss_tracker(m_L2cache->get_line_sz());
m_accessLocality = new L2c_access_locality(m_L2cache->get_line_sz());
@@ -401,7 +391,7 @@ void memory_partition_unit::L2c_service_mem_req()
address_type rep_block;
enum cache_request_status status = MISS_NO_WB;
if( mf->istexture() )
- status = m_L2cache->access( mf->get_addr(), mf->get_is_write(), gpu_sim_cycle, &rep_block);
+ status = m_L2cache->access( mf->get_partition_addr(), mf->get_is_write(), gpu_sim_cycle, &rep_block);
if( (status==HIT) || m_config->l2_ideal ) {
mf->set_type( REPLY_DATA );
assert( mf != NULL );
@@ -412,7 +402,6 @@ void memory_partition_unit::L2c_service_mem_req()
mf->set_status(IN_L2TOCBQUEUE_HIT,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle);
} else {
m_stats->L2_write_hit++;
- freed_L1write_mfs++;
gpgpu_n_processed_writes++;
}
} else {
@@ -484,7 +473,7 @@ void memory_partition_unit::process_dram_output()
mf->set_type(REPLY_DATA);
L2tocbqueue->push(mf,gpu_sim_cycle);
if( mf->istexture() )
- wb_addr = m_L2cache->shd_cache_fill(mf->get_addr(), gpu_sim_cycle);
+ wb_addr = m_L2cache->fill(mf->get_partition_addr(), gpu_sim_cycle);
}
// only perform a write on cache eviction (write-back policy)
// it is the 1st or nth time trial to writeback
@@ -501,7 +490,6 @@ void memory_partition_unit::process_dram_output()
wb_addr = -1;
} else { //service L2 write miss
m_missTracker->miss_serviced(mf);
- freed_L2write_mfs++;
mf->set_type(REPLY_DATA);
L2tocbqueue->push(mf,gpu_sim_cycle);
gpgpu_n_processed_writes++;
@@ -530,8 +518,8 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi
true/*write*/,
partial_write_mask_t(),
L2_WRBK_ACC,
- L2_WTBK_DATA );
- made_write_mfs++;
+ L2_WTBK_DATA,
+ m_config );
L2todram_wbqueue->push(mf,gpu_sim_cycle);
gpgpu_n_sent_writes++;
return true;
@@ -540,7 +528,7 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi
void memory_partition_unit::L2c_print_cache_stat(unsigned &accesses, unsigned &misses) const
{
FILE *fp = stdout;
- m_L2cache->shd_cache_print(fp,accesses,misses);
+ m_L2cache->print(fp,accesses,misses);
m_mshr->print_stat(fp);
m_missTracker->print_stat(fp);
m_accessLocality->print_stat(fp, false);
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index b2bafb2..b192986 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -167,11 +167,9 @@ private:
class memory_partition_unit
{
public:
- memory_partition_unit( unsigned partition_id, struct memory_config *config);
+ memory_partition_unit( unsigned partition_id, struct memory_config *config, class memory_stats_t *stats );
~memory_partition_unit();
- void set_stats( class memory_stats_t *stats );
-
void cache_cycle();
bool has_cache() { return m_L2cache != NULL; }
@@ -224,7 +222,7 @@ private:
// data
unsigned m_id;
- struct memory_config *m_config;
+ const struct memory_config *m_config;
class dram_t *m_dram;
class cache_t *m_L2cache;
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 50442c8..05835bf 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -82,7 +82,8 @@ mem_fetch::mem_fetch( new_addr_type addr,
bool write,
partial_write_mask_t partial_write_mask,
enum mem_access_type mem_acc,
- enum mf_type type )
+ enum mf_type type,
+ const memory_config *config )
{
m_request_uid = sm_next_mf_request_uid++;
@@ -95,7 +96,8 @@ mem_fetch::mem_fetch( new_addr_type addr,
m_mshr_id = mshr_id;
if( inst ) m_inst = *inst;
m_write = write;
- addrdec_tlx(addr,&m_raw_addr);
+ config->m_address_mapping.addrdec_tlx(addr,&m_raw_addr);
+ m_partition_addr = config->m_address_mapping.partition_address(addr);
m_mem_acc = mem_acc;
m_type = type;
m_timestamp = gpu_sim_cycle + gpu_tot_sim_cycle;
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index 31a47da..c922af5 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -144,7 +144,8 @@ public:
bool write,
partial_write_mask_t partial_write_mask,
enum mem_access_type mem_acc,
- enum mf_type type );
+ enum mf_type type,
+ const class memory_config *config );
void set_status( enum mshr_status status, enum mem_req_stat stat, unsigned long long cycle );
void set_type( enum mf_type t ) { m_type=t; }
@@ -157,6 +158,7 @@ public:
unsigned get_ctrl_size() const { return m_ctrl_size; }
unsigned size() const { return m_data_size+m_ctrl_size; }
new_addr_type get_addr() const { return m_addr; }
+ new_addr_type get_partition_addr() const { return m_partition_addr; }
unsigned get_mshr() { return m_mshr_id; }
bool get_is_write() const { return m_write; }
unsigned get_request_uid() const { return m_request_uid; }
@@ -185,25 +187,26 @@ private:
unsigned m_wid;
unsigned m_mshr_id;
- // where is the request now?
+ // where is this request now?
enum mshr_status m_status;
// request type, address, size, mask
bool m_write;
enum mem_access_type m_mem_acc;
enum mf_type m_type;
- new_addr_type m_addr;
- addrdec_t m_raw_addr;
- partial_write_mask_t m_write_mask;
- unsigned m_data_size; // bytes
- unsigned m_ctrl_size;
+ new_addr_type m_addr; // linear (physical) address
+ new_addr_type m_partition_addr; // linear physical address *within* dram partition (partition bank select bits squeezed out)
+ addrdec_t m_raw_addr; // raw physical address (i.e., decoded DRAM chip-row-bank-column address)
+ partial_write_mask_t m_write_mask;
+ unsigned m_data_size; // how much data is being written
+ unsigned m_ctrl_size; // how big would all this meta data be in hardware (does not necessarily match actual size of mem_fetch)
// statistics
unsigned m_timestamp; // set to gpu_sim_cycle+gpu_tot_sim_cycle at struct creation
unsigned m_timestamp2; // set to gpu_sim_cycle+gpu_tot_sim_cycle when pushed onto icnt to shader; only used for reads
unsigned m_icnt_receive_time; // set to gpu_sim_cycle + interconnect_latency when fixed icnt latency mode is enabled
- // requesting instruction
+ // requesting instruction (put last so mem_fetch prints nicer in gdb)
warp_inst_t m_inst;
static unsigned sm_next_mf_request_uid;
diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index fda42e5..2087fd2 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -79,12 +79,27 @@
#include <stdlib.h>
#include <stdio.h>
-memory_stats_t::memory_stats_t( unsigned n_mem, unsigned n_shader, struct shader_core_config *shader_config, struct memory_config *mem_config )
+memory_stats_t::memory_stats_t( unsigned n_shader, struct shader_core_config *shader_config, struct memory_config *mem_config )
{
unsigned i,j;
+
+ concurrent_row_access = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ num_activates = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ row_access = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ max_conc_access2samerow = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ max_servicetime2samerow = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+
+ for (unsigned i=0;i<mem_config->m_n_mem ;i++ ) {
+ concurrent_row_access[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ row_access[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ num_activates[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ max_conc_access2samerow[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ max_servicetime2samerow[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ }
+
+
m_n_shader=n_shader;
- m_n_mem=n_mem;
m_memory_config=mem_config;
max_mrq_latency = 0;
@@ -104,46 +119,46 @@ memory_stats_t::memory_stats_t( unsigned n_mem, unsigned n_shader, struct shader
mf_tot_lat_pw_perwarp = (unsigned *) calloc(max_warps, sizeof(unsigned int));
mf_total_lat_perwarp = (unsigned long long int *) calloc(max_warps, sizeof(unsigned long long int));
num_mfs_perwarp = (unsigned *) calloc(max_warps, sizeof(unsigned int));
- acc_mrq_length = (unsigned *) calloc(n_mem, sizeof(unsigned int));
+ acc_mrq_length = (unsigned *) calloc(mem_config->m_n_mem, sizeof(unsigned int));
mf_tot_lat_pw = 0; //total latency summed up per window. divide by mf_num_lat_pw to obtain average latency Per Window
mf_total_lat = 0;
num_mfs = 0;
printf("*** Initializing Memory Statistics ***\n");
- totalbankreads = (unsigned int**) calloc(n_mem, sizeof(unsigned int*));
- totalbankwrites = (unsigned int**) calloc(n_mem, sizeof(unsigned int*));
- totalbankaccesses = (unsigned int**) calloc(n_mem, sizeof(unsigned int*));
- mf_total_lat_table = (unsigned long long int **) calloc(n_mem, sizeof(unsigned long long *));
- mf_max_lat_table = (unsigned **) calloc(n_mem, sizeof(unsigned *));
+ totalbankreads = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ totalbankwrites = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ totalbankaccesses = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ mf_total_lat_table = (unsigned long long int **) calloc(mem_config->m_n_mem, sizeof(unsigned long long *));
+ mf_max_lat_table = (unsigned **) calloc(mem_config->m_n_mem, sizeof(unsigned *));
bankreads = (unsigned int***) calloc(n_shader, sizeof(unsigned int**));
bankwrites = (unsigned int***) calloc(n_shader, sizeof(unsigned int**));
- num_MCBs_accessed = (unsigned int*) calloc(n_mem*mem_config->gpu_mem_n_bk, sizeof(unsigned int));
+ num_MCBs_accessed = (unsigned int*) calloc(mem_config->m_n_mem*mem_config->nbk, sizeof(unsigned int));
if (mem_config->gpgpu_dram_sched_queue_size) {
position_of_mrq_chosen = (unsigned int*) calloc(mem_config->gpgpu_dram_sched_queue_size, sizeof(unsigned int));
} else
position_of_mrq_chosen = (unsigned int*) calloc(1024, sizeof(unsigned int));
for (i=0;i<n_shader ;i++ ) {
- bankreads[i] = (unsigned int**) calloc(n_mem, sizeof(unsigned int*));
- bankwrites[i] = (unsigned int**) calloc(n_mem, sizeof(unsigned int*));
- for (j=0;j<n_mem ;j++ ) {
- bankreads[i][j] = (unsigned int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned int));
- bankwrites[i][j] = (unsigned int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned int));
+ bankreads[i] = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ bankwrites[i] = (unsigned int**) calloc(mem_config->m_n_mem, sizeof(unsigned int*));
+ for (j=0;j<mem_config->m_n_mem ;j++ ) {
+ bankreads[i][j] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ bankwrites[i][j] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
}
}
- for (i=0;i<n_mem ;i++ ) {
- totalbankreads[i] = (unsigned int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned int));
- totalbankwrites[i] = (unsigned int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned int));
- totalbankaccesses[i] = (unsigned int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned int));
- mf_total_lat_table[i] = (unsigned long long int*) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned long long int));
- mf_max_lat_table[i] = (unsigned *) calloc(mem_config->gpu_mem_n_bk, sizeof(unsigned));
+ for (i=0;i<mem_config->m_n_mem ;i++ ) {
+ totalbankreads[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ totalbankwrites[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ totalbankaccesses[i] = (unsigned int*) calloc(mem_config->nbk, sizeof(unsigned int));
+ mf_total_lat_table[i] = (unsigned long long int*) calloc(mem_config->nbk, sizeof(unsigned long long int));
+ mf_max_lat_table[i] = (unsigned *) calloc(mem_config->nbk, sizeof(unsigned));
}
mem_access_type_stats = (unsigned ***) malloc(NUM_MEM_ACCESS_TYPE * sizeof(unsigned **));
for (i = 0; i < NUM_MEM_ACCESS_TYPE; i++) {
int j;
- mem_access_type_stats[i] = (unsigned **) calloc(n_mem, sizeof(unsigned*));
- for (j=0; (unsigned) j< n_mem; j++) {
- mem_access_type_stats[i][j] = (unsigned *) calloc((mem_config->gpu_mem_n_bk+1), sizeof(unsigned*));
+ mem_access_type_stats[i] = (unsigned **) calloc(mem_config->m_n_mem, sizeof(unsigned*));
+ for (j=0; (unsigned) j< mem_config->m_n_mem; j++) {
+ mem_access_type_stats[i][j] = (unsigned *) calloc((mem_config->nbk+1), sizeof(unsigned*));
}
}
@@ -151,12 +166,12 @@ memory_stats_t::memory_stats_t( unsigned n_mem, unsigned n_shader, struct shader
L2_write_hit=0;
L2_read_hit=0;
L2_read_miss=0;
- L2_cbtoL2length = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
- L2_cbtoL2writelength = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
- L2_L2tocblength = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
- L2_dramtoL2length = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
- L2_dramtoL2writelength = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
- L2_L2todramlength = (unsigned int*) calloc(n_mem, sizeof(unsigned int));
+ L2_cbtoL2length = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
+ L2_cbtoL2writelength = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
+ L2_L2tocblength = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
+ L2_dramtoL2length = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
+ L2_dramtoL2writelength = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
+ L2_L2todramlength = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
}
// recorder the total latency
diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h
index c2a09b7..14868ef 100644
--- a/src/gpgpu-sim/mem_latency_stat.h
+++ b/src/gpgpu-sim/mem_latency_stat.h
@@ -72,8 +72,7 @@
class memory_stats_t {
public:
- memory_stats_t( unsigned n_mem,
- unsigned n_shader,
+ memory_stats_t( unsigned n_shader,
struct shader_core_config *shader_config,
struct memory_config *mem_config );
@@ -88,7 +87,6 @@ public:
void print( FILE *fp );
- unsigned m_n_mem;
unsigned m_n_shader;
const struct shader_core_config *m_shader_config;
@@ -139,6 +137,12 @@ public:
unsigned int *L2_dramtoL2length;
unsigned int *L2_dramtoL2writelength;
unsigned int *L2_L2todramlength;
+
+ unsigned int **concurrent_row_access; //concurrent_row_access[dram chip id][bank id]
+ unsigned int **num_activates; //num_activates[dram chip id][bank id]
+ unsigned int **row_access; //row_access[dram chip id][bank id]
+ unsigned int **max_conc_access2samerow; //max_conc_access2samerow[dram chip id][bank id]
+ unsigned int **max_servicetime2samerow; //max_servicetime2samerow[dram chip id][bank id]
};
#endif /*MEM_LATENCY_STAT_H*/
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index ae62b97..a316fbb 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -239,7 +239,7 @@ std::list<mshr_entry*> &mshr_shader_unit::choose_return_queue()
void mshr_shader_unit::mshr_return_from_mem(unsigned mshr_id)
{
- if(mshr_id == -1) {
+ if(mshr_id == (unsigned)-1) {
return;
}
mshr_entry *mshr = &m_mshrs[mshr_id];
@@ -294,12 +294,14 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
unsigned shader_id,
unsigned tpc_id,
struct shader_core_config *config,
+ const struct memory_config *mem_config,
struct shader_core_stats *stats )
: m_barriers( config->max_warps_per_shader, config->max_cta_per_core )
{
- m_gpu = gpu;
+ m_gpu = gpu;
m_cluster = cluster;
m_config = config;
+ m_memory_config = mem_config;
m_stats = stats;
unsigned warp_size=config->warp_size;
config->max_sfu_latency = 32;
@@ -330,7 +332,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
#define STRSIZE 1024
char L1I_name[STRSIZE];
snprintf(L1I_name, STRSIZE, "L1I_%03d", m_sid);
- m_L1I = new cache_t(L1I_name,m_config->gpgpu_cache_il1_opt, 0,no_writes, m_sid,get_shader_instruction_cache_id());
+ m_L1I = new cache_t(L1I_name,m_config->gpgpu_cache_il1_opt,no_writes,m_sid,get_shader_instruction_cache_id());
m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size));
m_pdom_warp = new pdom_warp_ctx_t*[config->max_warps_per_shader];
@@ -364,7 +366,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_dispatch_port[1] = ID_OC_SFU;
m_issue_port[1] = OC_EX_SFU;
- m_ldst_unit = new ldst_unit( m_cluster, this, &m_operand_collector, m_scoreboard, config, m_stats, m_sid, m_tpc );
+ m_ldst_unit = new ldst_unit( cluster, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id );
m_fu[2] = m_ldst_unit;
m_dispatch_port[2] = ID_OC_MEM;
m_issue_port[2] = OC_EX_MEM;
@@ -628,7 +630,8 @@ void shader_core_ctx::fetch()
false,
NO_PARTIAL_WRITE,
INST_ACC_R,
- RD_REQ );
+ RD_REQ,
+ m_memory_config );
m_cluster->icnt_inject_request_packet(mf);
m_warp[warp_id].set_imiss_pending();
@@ -1047,7 +1050,8 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
true,
NO_PARTIAL_WRITE,
inst.space.is_local()?LOCAL_ACC_W:GLOBAL_ACC_W, //space of cache line is same as new request
- WT_REQ );
+ WT_REQ,
+ m_memory_config );
m_cluster->icnt_inject_request_packet(mf);
inst.clear_active(access.warp_indices);
m_stats->L1_writeback++;
@@ -1125,7 +1129,8 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
is_write,
write_mask,
access_type,
- is_write?WT_REQ:RD_REQ);
+ is_write?WT_REQ:RD_REQ,
+ m_memory_config);
if( access.reserved_mshr )
access.reserved_mshr->set_mf(mf);
m_cluster->icnt_inject_request_packet(mf);
@@ -1399,11 +1404,13 @@ ldst_unit::ldst_unit( simt_core_cluster *cluster,
shader_core_ctx *core,
opndcoll_rfu_t *operand_collector,
Scoreboard *scoreboard,
- shader_core_config *config,
+ shader_core_config *config,
+ const memory_config *mem_config,
shader_core_stats *stats,
unsigned sid,
unsigned tpc ) : pipelined_simd_unit(NULL,config,6)
{
+ m_memory_config = mem_config;
m_cluster = cluster;
m_core = core;
m_operand_collector = operand_collector;
@@ -1419,9 +1426,9 @@ ldst_unit::ldst_unit( simt_core_cluster *cluster,
snprintf(L1T_name, STRSIZE, "L1T_%03d", m_sid);
snprintf(L1C_name, STRSIZE, "L1C_%03d", m_sid);
enum cache_write_policy L1D_policy = m_config->gpgpu_cache_wt_through?write_through:write_back;
- m_L1D = new cache_t(L1D_name,m_config->gpgpu_cache_dl1_opt,0,L1D_policy,m_sid,get_shader_normal_cache_id());
- m_L1T = new cache_t(L1T_name,m_config->gpgpu_cache_texl1_opt,0,no_writes, m_sid,get_shader_texture_cache_id());
- m_L1C = new cache_t(L1C_name,m_config->gpgpu_cache_constl1_opt,0,no_writes, m_sid,get_shader_constant_cache_id());
+ m_L1D = new cache_t(L1D_name,m_config->gpgpu_cache_dl1_opt,L1D_policy,m_sid,get_shader_normal_cache_id());
+ m_L1T = new cache_t(L1T_name,m_config->gpgpu_cache_texl1_opt,no_writes, m_sid,get_shader_texture_cache_id());
+ m_L1C = new cache_t(L1C_name,m_config->gpgpu_cache_constl1_opt,no_writes, m_sid,get_shader_constant_cache_id());
config->gpgpu_cache_dl1_linesize = m_L1D->get_line_sz();
config->gpgpu_cache_texl1_linesize = m_L1T->get_line_sz();
config->gpgpu_cache_constl1_linesize = m_L1C->get_line_sz();
@@ -1467,11 +1474,11 @@ void ldst_unit::writeback()
}
m_mshr_unit->mshr_return_from_mem(mf->get_mshr());
if (mf->istexture())
- m_L1T->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1T->fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
else if (mf->isconst())
- m_L1C->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1C->fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
else if (!m_config->gpgpu_no_dl1)
- m_L1D->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1D->fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
delete mf;
}
}
@@ -2098,7 +2105,7 @@ bool shader_core_ctx::fetch_unit_response_buffer_full() const
void shader_core_ctx::accept_fetch_response( mem_fetch *mf )
{
- m_L1I->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1I->fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
m_warp[mf->get_wid()].clear_imiss_pending();
delete mf;
}
@@ -2450,6 +2457,7 @@ class ptx_thread_info *shader_core_ctx::get_thread_state( unsigned hw_thread_id
simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu,
unsigned cluster_id,
struct shader_core_config *config,
+ const struct memory_config *mem_config,
struct shader_core_stats *stats )
{
m_cta_issue_next_core=0;
@@ -2459,7 +2467,7 @@ simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu,
m_stats = stats;
m_core = new shader_core_ctx*[ config->n_simt_cores_per_cluster ];
for( unsigned i=0; i < config->n_simt_cores_per_cluster; i++ )
- m_core[i] = new shader_core_ctx(gpu,this,cid_to_sid(i),m_cluster_id,config,stats);
+ m_core[i] = new shader_core_ctx(gpu,this,cid_to_sid(i),m_cluster_id,config,mem_config,stats);
}
void simt_core_cluster::core_cycle()
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index b516495..85d5ac1 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -983,11 +983,12 @@ class simt_core_cluster;
class ldst_unit: public pipelined_simd_unit {
public:
- ldst_unit( simt_core_cluster *gpu,
+ ldst_unit( simt_core_cluster *cluster,
shader_core_ctx *core,
opndcoll_rfu_t *operand_collector,
Scoreboard *scoreboard,
shader_core_config *config,
+ const memory_config *mem_config,
shader_core_stats *stats,
unsigned sid, unsigned tpc );
@@ -1034,6 +1035,7 @@ private:
warp_inst_t &inst );
mem_stage_stall_type send_mem_request(warp_inst_t &inst, mem_access_t &access);
+ const memory_config *m_memory_config;
class simt_core_cluster *m_cluster;
class shader_core_ctx *m_core;
unsigned m_sid;
@@ -1072,6 +1074,7 @@ public:
unsigned shader_id,
unsigned tpc_id,
struct shader_core_config *config,
+ const struct memory_config *mem_config,
struct shader_core_stats *stats );
void issue_block2core( class kernel_info_t &kernel );
@@ -1142,6 +1145,7 @@ private:
unsigned m_sid; // shader id
unsigned m_tpc; // texture processor cluster id (aka, node id when using interconnect concentration)
const shader_core_config *m_config;
+ const memory_config *m_memory_config;
class simt_core_cluster *m_cluster;
class gpgpu_sim *m_gpu;
@@ -1187,6 +1191,7 @@ public:
simt_core_cluster( class gpgpu_sim *gpu,
unsigned cluster_id,
struct shader_core_config *config,
+ const struct memory_config *mem_config,
struct shader_core_stats *stats );
void core_cycle();