diff options
| author | Tor Aamodt <[email protected]> | 2010-10-16 11:59:28 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-10-16 11:59:28 -0800 |
| commit | 58459bf7a55010eccf9940cfdb53cbc854b0989c (patch) | |
| tree | cbbace76fa7d517cc1b1c6d2d7789a851289df96 /src/gpgpu-sim | |
| parent | 6c33482bbdbcd289e6ee14605b0f2698c151c5af (diff) | |
1. moving address decoding into a class (and out of cache entirely)
2. moving DRAM timing parameters into memory_config class
3. removing some likely useless statistics
4. other cleaning up of code
passing CUDA 3.1 regression
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7868]
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/addrdec.cc | 252 | ||||
| -rw-r--r-- | src/gpgpu-sim/addrdec.h | 55 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.cc | 85 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.h | 22 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram_sched.cc | 58 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram_sched.h | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 162 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 71 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 73 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 50 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 34 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.h | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.cc | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.h | 19 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.cc | 73 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.h | 10 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 40 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 7 |
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(); |
