summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-02 14:54:02 -0800
committerTor Aamodt <[email protected]>2010-10-02 14:54:02 -0800
commitd3b9d526ecbf5e0bdaa91d21526cb56a2e98b534 (patch)
treed419ff51749e24fb2f30314d42496f25a692561a
parent11b308e7363e937966b035b4891db32b4eece3bf (diff)
refactoring: make shd_cache_t into a class (cache_t), plus some other cleaning up
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7806]
-rw-r--r--src/gpgpu-sim/delayqueue.h2
-rw-r--r--src/gpgpu-sim/dram.cc31
-rw-r--r--src/gpgpu-sim/dram.h1
-rw-r--r--src/gpgpu-sim/gpu-cache.cc271
-rw-r--r--src/gpgpu-sim/gpu-cache.h94
-rw-r--r--src/gpgpu-sim/gpu-misc.cc14
-rw-r--r--src/gpgpu-sim/gpu-misc.h18
-rw-r--r--src/gpgpu-sim/gpu-sim.cc56
-rw-r--r--src/gpgpu-sim/l2cache.cc243
-rw-r--r--src/gpgpu-sim/l2cache.h30
-rw-r--r--src/gpgpu-sim/mem_fetch.cc6
-rw-r--r--src/gpgpu-sim/mem_fetch.h3
-rw-r--r--src/gpgpu-sim/shader.cc110
-rw-r--r--src/gpgpu-sim/shader.h14
14 files changed, 318 insertions, 575 deletions
diff --git a/src/gpgpu-sim/delayqueue.h b/src/gpgpu-sim/delayqueue.h
index 8392460..050a916 100644
--- a/src/gpgpu-sim/delayqueue.h
+++ b/src/gpgpu-sim/delayqueue.h
@@ -156,7 +156,7 @@ public:
return data;
}
- T* top()
+ T* top() const
{
if (m_head) {
return m_head->m_data;
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index 3182b38..fe1b470 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -411,12 +411,8 @@ void dram_t::issueCMD()
//if mrq is being serviced by dram, gets popped after CL latency fulfilled
class mem_fetch* dram_t::pop()
{
- dram_req_t *mrq;
- class mem_fetch *data;
- unsigned dq_latency;
-
- data = NULL;
- mrq = rwq->pop(gpu_sim_cycle);
+ class mem_fetch *data = NULL;
+ dram_req_t *mrq = rwq->pop(gpu_sim_cycle);
if (mrq) {
#ifdef DRAM_VIEWCMD
printf("\tDQ: BK%d Row:%03x Col:%03x",
@@ -425,7 +421,7 @@ class mem_fetch* dram_t::pop()
mrq->dqbytes += BL * busW * gpu_n_mem_per_ctrlr; /*16 bytes*/
if (mrq->dqbytes >= mrq->nbytes) {
if (m_config->gpgpu_memlatency_stat) {
- dq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - mrq->timestamp;
+ unsigned dq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - mrq->timestamp;
m_stats->dq_lat_table[LOGB2(dq_latency)]++;
if (dq_latency > m_stats->max_dq_latency)
m_stats->max_dq_latency = dq_latency;
@@ -437,7 +433,6 @@ class mem_fetch* dram_t::pop()
#ifdef DRAM_VIEWCMD
printf("\n");
#endif
-
return data;
}
@@ -456,26 +451,6 @@ class mem_fetch* dram_t::returnq_top()
return returnq->top();
}
-
-// a hack to allow peeking into what memory request will be serviced.
-class mem_fetch* dram_t::top()
-{
- dram_req_t *mrq;
- class mem_fetch *data;
-
- data = NULL;
- mrq = rwq->top();
- if (mrq) {
- // number of bytes returned from dram if this is ever popped
- unsigned tobe_dqbytes = mrq->dqbytes + BL * busW * gpu_n_mem_per_ctrlr;
- if (tobe_dqbytes >= mrq->nbytes) {
- data = mrq->data;
- }
- }
-
- return data;
-}
-
void dram_t::print( FILE* simFile) const
{
unsigned i;
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index 68b2474..ee7f7a7 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -128,7 +128,6 @@ public:
void set_stats( class memory_stats_t *stats ) {m_stats=stats;}
int full();
- class mem_fetch* top();
void print( FILE* simFile ) const;
void visualize() const;
void print_stat( FILE* simFile );
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index bfd8772..164c3fd 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -72,20 +72,17 @@
#include <assert.h>
#include <string.h>
-// both shd_cache_access and shd_cache_probe functions use
-// shd_cache_access_internal to access/probe cache
-shd_cache_line_t* shd_cache_access_internal( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle,
- unsigned int real_access);
+cache_t::~cache_t()
+{
+ delete m_lines;
+}
-shd_cache_t * shd_cache_create( const char *name,
- const char *opt,
- unsigned int hit_latency,
- unsigned long long int bank_mask,
- enum cache_write_policy wp)
+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)
{
unsigned int nset;
unsigned int line_sz;
@@ -96,36 +93,29 @@ shd_cache_t * shd_cache_create( const char *name,
printf("GPGPU-Sim uArch: cache configuration string parsing error for cache %s\n", name);
abort();
}
+ assert(nset && assoc);
- shd_cache_t *cp;
+ cache_t *cp = this;
unsigned int nlines;
-
unsigned int i;
- if (!nset || !assoc) {
- printf("Creating non-existing cache!\n");
- return 0;
- }
nlines = nset * assoc;
- cp = (shd_cache_t*) calloc(1, sizeof(shd_cache_t));
-
cp->bank_mask = bank_mask;
- cp->name = (char*) malloc(sizeof(char) * (strlen(name) + 1));
- strcpy(cp->name, name);
- cp->nset = nset;
- cp->nset_log2 = LOGB2(nset);
- cp->assoc = assoc;
- cp->line_sz = line_sz;
+ 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->hit_latency = hit_latency;
- cp->lines = (shd_cache_line_t*) calloc(nlines, sizeof(shd_cache_line_t));
+ cp->m_lines = (cache_block_t*) calloc(nlines, sizeof(cache_block_t));
cp->write_policy = wp;
for (i=0; i<nlines; i++) {
- cp->lines[i].line_sz = line_sz;
- cp->lines[i].status = 0;
+ cp->m_lines[i].line_sz = line_sz;
+ cp->m_lines[i].status = 0;
}
// don't hook up with any logger
@@ -136,104 +126,35 @@ shd_cache_t * shd_cache_create( const char *name,
cp->prev_snapshot_access = 0;
cp->prev_snapshot_miss = 0;
cp->prev_snapshot_merge_hit = 0;
-
- return cp;
-}
-
-void shd_cache_destroy( shd_cache_t* cp ) {
-
- free(cp->lines);
- free(cp);
-}
-
-// hook up with shader core logger
-void shd_cache_bind_logger(shd_cache_t* cp, int core_id, int type_id) {
cp->core_id = core_id;
cp->type_id = type_id;
}
-shd_cache_line_t* shd_cache_access_internal( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle,
- unsigned int real_access) {
- //if real_access==0 then its only a cache probe stats and LRU tags should not be updated
- unsigned int i;
- unsigned int set;
- unsigned long long int tag;
- unsigned long long int packed_addr;
- shd_cache_line_t *pline;
-
- if (cp->bank_mask)
- packed_addr = addrdec_packbits(cp->bank_mask, addr, 64, 0);
- else
- packed_addr = addr;
-
- set = (packed_addr >> cp->line_sz_log2) & ( (1<<cp->nset_log2) - 1 );
- tag = packed_addr >> (cp->line_sz_log2 + cp->nset_log2);
-
- if (real_access) {
- cp->access++;
- shader_cache_access_log(cp->core_id, cp->type_id, 0);
- }
-
- for (i=0; i<cp->assoc; i++) {
- pline = &(cp->lines[set*cp->assoc+i] );
- if (pline->status & VALID) {
- if (pline->tag == tag) {
- //printf("Cache Hit! Addr=%08x Set=%x Way=%x Tag=%x\n", packed_addr, set, i, tag);
- if (real_access) {
- pline->last_used = sim_cycle;
- if (write) {
- pline->status |= DIRTY;
- }
- }
- return pline;
- }
- }
- }
- if (real_access) {
- cp->miss++;
- shader_cache_access_log(cp->core_id, cp->type_id, 1);
- }
- return 0;
-}
-
-shd_cache_line_t* shd_cache_access( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle )
-{
- assert( cp->write_policy != write_back );
- return shd_cache_access_internal(cp,addr,nbytes,write,sim_cycle,1/*this is a real access*/);
-}
-
-enum cache_request_status shd_cache_access_new( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle, address_type *wb_address)
+enum cache_request_status cache_t::access( unsigned long long int addr,
+ unsigned int nbytes,
+ unsigned char write,
+ unsigned int sim_cycle,
+ address_type *wb_address )
{
+ cache_t *cp = this;
unsigned long long int bank_addr; // offset within bank
bool all_reserved = true;
- shd_cache_line_t *pending_line = NULL;
- shd_cache_line_t *clean_line = NULL;
+ cache_block_t *pending_line = NULL;
+ cache_block_t *clean_line = NULL;
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->nset_log2) - 1 );
- unsigned long long tag = bank_addr >> (cp->line_sz_log2 + cp->nset_log2);
+ 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);
- cp->access++;
+ cp->m_access++;
shader_cache_access_log(cp->core_id, cp->type_id, 0);
- for (unsigned way=0; way<cp->assoc; way++) {
- shd_cache_line_t *line = &(cp->lines[set*cp->assoc+way] );
+ for (unsigned way=0; way<cp->m_assoc; way++) {
+ cache_block_t *line = &(cp->m_lines[set*cp->m_assoc+way] );
if (line->tag == tag) {
if (line->status & RESERVED) {
pending_line = line;
@@ -283,10 +204,10 @@ enum cache_request_status shd_cache_access_new( shd_cache_t *cp,
}
// no clean lines, need to kick a line out to reserve a spot
- shd_cache_line_t *wb_line = NULL;
+ cache_block_t *wb_line = NULL;
- for (unsigned way=0; way<cp->assoc; way++) {
- shd_cache_line_t *line = &(cp->lines[set*cp->assoc+way] );
+ for (unsigned way=0; way<cp->m_assoc; way++) {
+ cache_block_t *line = &(cp->m_lines[set*cp->m_assoc+way] );
if (line->status & VALID && !(line->status & RESERVED)) {
if (!wb_line) {
wb_line = line;
@@ -317,91 +238,56 @@ enum cache_request_status shd_cache_access_new( shd_cache_t *cp,
return MISS_W_WB;
}
-shd_cache_line_t* shd_cache_probe( shd_cache_t *cp,
- unsigned long long int addr)
-{
- return shd_cache_access_internal(cp,addr,
- 1,0,0, /*do not matter*/
- 0/*this is just a probe*/);
-}
-
-void shd_cache_undo_stats( shd_cache_t *cp, int miss )
-{
- if (miss) {
- cp->miss--;
- shader_cache_access_unlog(cp->core_id, cp->type_id, 1);
- }
- cp->access--;
- shader_cache_access_unlog(cp->core_id, cp->type_id, 0);
-}
-
// Obtain the windowed cache miss rate for visualizer
-float shd_cache_windowed_cache_miss_rate( shd_cache_t *cp, int minus_merge_hit )
+float cache_t::shd_cache_windowed_cache_miss_rate( int minus_merge_hit )
{
- unsigned int n_access = cp->access - cp->prev_snapshot_access;
+ 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;
- if (minus_merge_hit) {
+ if (minus_merge_hit)
n_miss -= n_merge_hit;
- }
float missrate = 0.0f;
- if (n_access != 0) {
+ if (n_access != 0)
missrate = (float) n_miss / n_access;
- }
return missrate;
}
// start a new sampling window
-void shd_cache_new_window( shd_cache_t *cp )
+void cache_t::shd_cache_new_window()
{
- cp->prev_snapshot_access = cp->access;
+ 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;
}
-unsigned long long int L2_shd_cache_fill( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int sim_cycle ) {
- unsigned long long int result = shd_cache_fill(cp, addr, sim_cycle);
- return result;
-}
-
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.
-unsigned long long int shd_cache_fill( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int sim_cycle ) {
-
- unsigned int i;
- unsigned int set;
- unsigned long long int tag;
- unsigned long long int packed_addr;
- unsigned long long int repl_addr;
-
- unsigned char nofreeslot;
- unsigned char line_exists;
+new_addr_type cache_t::shd_cache_fill( new_addr_type addr, unsigned int sim_cycle )
+{
+ cache_t *cp = this;
unsigned int base = 0 ;
- unsigned int maxway = cp->assoc ;
-
- shd_cache_line_t *pline, *cline;
-
+ unsigned int maxway = cp->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;
- set = (packed_addr >> cp->line_sz_log2) & ( (1<<cp->nset_log2) - 1 );
- tag = packed_addr >> (cp->line_sz_log2 + cp->nset_log2);
+ 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);
if (cp->write_policy == write_back) {
//this request must have a reserved spot
cline = NULL;
- for (i=base; i<maxway; i++) {
- pline = &(cp->lines[set*cp->assoc+i] );
+ for (unsigned i=base; i<maxway; i++) {
+ pline = &(cp->m_lines[set*cp->m_assoc+i] );
if ((pline->tag == tag) && (pline->status & RESERVED)) {
cline = pline;
break;
@@ -435,17 +321,17 @@ unsigned long long int shd_cache_fill( shd_cache_t *cp,
//behavior unchanged for write through cache... probably not all necessary.
// Look for any free slots and the possibility that the line is in the cache already
- nofreeslot = 1;
- line_exists = 0;
- for (i=base; i<maxway; i++) {
- pline = &(cp->lines[set*cp->assoc+i] );
+ bool nofreeslot = true;
+ bool line_exists = false;
+ for (unsigned i=base; i<maxway; i++) {
+ pline = &(cp->m_lines[set*cp->m_assoc+i] );
if (!(pline->status & VALID)) {
cline = pline;
- nofreeslot = 0;
+ nofreeslot = false;
break;
} else if (pline->tag == tag) {
cline = pline;
- line_exists = 1;
+ line_exists = true;
break;
}
}
@@ -456,9 +342,9 @@ unsigned long long int shd_cache_fill( shd_cache_t *cp,
}
if (nofreeslot) {
- cline = &(cp->lines[set*cp->assoc+base] );
- for (i=1+base; i<maxway; i++) {
- pline = &(cp->lines[set*cp->assoc+i] );
+ cline = &(cp->m_lines[set*cp->m_assoc+base] );
+ for (unsigned i=1+base; i<maxway; i++) {
+ pline = &(cp->m_lines[set*cp->m_assoc+i] );
if (pline->status & VALID) {
switch (cp->policy) {
case LRU:
@@ -477,6 +363,7 @@ unsigned long long int shd_cache_fill( shd_cache_t *cp,
}
/* Set the replaced cache line address */
+ unsigned long long int repl_addr;
if ((cline->status & (DIRTY|VALID)) == (DIRTY|VALID)) {
repl_addr = cline->addr;
} else {
@@ -494,20 +381,30 @@ unsigned long long int shd_cache_fill( shd_cache_t *cp,
return repl_addr;
}
-void shd_cache_mergehit( shd_cache_t *cp, unsigned long long int addr )
+unsigned int cache_t::flush()
{
- cp->merge_hit += 1;
+ 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) ) {
+ dirty_lines_flushed++;
+ }
+ cp->m_lines[i].status &= ~VALID;
+ cp->m_lines[i].status &= ~DIRTY;
+ }
+ return dirty_lines_flushed;
}
-void shd_cache_print( const shd_cache_t *cp, FILE *stream, unsigned &total_access, unsigned &total_misses )
+void cache_t::shd_cache_print( FILE *stream, unsigned &total_access, unsigned &total_misses )
{
- fprintf( stream, "Cache %s:\t", cp->name);
+ cache_t *cp = this;
+ fprintf( stream, "Cache %s:\t", cp->m_name);
fprintf( stream, "Size = %d B (%d Set x %d-way x %d byte line)\n",
- cp->line_sz * cp->nset * cp->assoc,
- cp->nset, cp->assoc, cp->line_sz );
+ cp->m_line_sz * cp->m_nset * cp->m_assoc,
+ cp->m_nset, cp->m_assoc, cp->m_line_sz );
fprintf( stream, "\t\tAccess = %d, Miss = %d (%.3g), -MgHts = %d (%.3g)\n",
- cp->access, cp->miss, (float) cp->miss / cp->access,
- cp->miss - cp->merge_hit, (float) (cp->miss - cp->merge_hit) / cp->access);
+ 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->access;
+ total_access+=cp->m_access;
}
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 3b4bf73..6efb42d 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -85,8 +85,7 @@ enum cache_request_status {
NUM_CACHE_REQUEST_STATUS
};
-
-struct shd_cache_line_t {
+struct cache_block_t {
unsigned long long int tag;
unsigned long long int addr;
unsigned int set;
@@ -96,7 +95,6 @@ struct shd_cache_line_t {
unsigned char status; /* valid, dirty... etc */
};
-
#define LRU 'L'
#define FIFO 'F'
#define RANDOM 'R'
@@ -107,21 +105,44 @@ enum cache_write_policy{
write_through //reservation based, use much handle reservation full error.
};
-struct shd_cache_t {
+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 int nbytes,
+ unsigned char write,
+ unsigned int sim_cycle,
+ address_type *wb_address);
- char *name;
+ new_addr_type shd_cache_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();
+ unsigned get_line_sz() const { return m_line_sz; }
- shd_cache_line_t *lines; /* nset x assoc lines in total */
- unsigned int nset;
- unsigned int nset_log2;
- unsigned int assoc;
- unsigned int line_sz; // bytes
+private:
+ char *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;
- unsigned int hit_latency;
- unsigned int access;
+ 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)
@@ -135,54 +156,7 @@ struct shd_cache_t {
unsigned long long int bank_mask;
+ class linear_histogram_logger *m_logger;
};
-shd_cache_t * shd_cache_create( const char *name,
- const char *opt,
- unsigned int hit_latency,
- unsigned long long int bank_mask,
- enum cache_write_policy wp);
-
-void shd_cache_destroy( shd_cache_t* cp );
-
-// hook up with shader core logger
-void shd_cache_bind_logger(shd_cache_t* cp, int core_id, int type_id);
-
-// depricated use shd_cache_access_new
-shd_cache_line_t* shd_cache_access( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle );
-
-enum cache_request_status shd_cache_access_new( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int nbytes,
- unsigned char write,
- unsigned int sim_cycle,
- address_type *wb_address);
-
-
-//just probe the tag array to see if addr is in the cache or not
-//does not update LRU or stats...
-shd_cache_line_t* shd_cache_probe( shd_cache_t *cp,
- unsigned long long int addr);
-
-// undo the statistic record when the memory access is stalled/squashed and will try again next cycle
-void shd_cache_undo_stats( shd_cache_t *cp, int miss );
-
-void shd_cache_mergehit( shd_cache_t *cp, unsigned long long int addr );
-
-unsigned long long int shd_cache_fill( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int sim_cycle );
-
-unsigned long long int L2_shd_cache_fill( shd_cache_t *cp,
- unsigned long long int addr,
- unsigned int sim_cycle );
-
-void shd_cache_print( const shd_cache_t *cp, FILE *stream, unsigned &total_access, unsigned &total_misses );
-float shd_cache_windowed_cache_miss_rate(shd_cache_t*, int);
-void shd_cache_new_window(shd_cache_t*);
-
#endif
diff --git a/src/gpgpu-sim/gpu-misc.cc b/src/gpgpu-sim/gpu-misc.cc
index 06a0f68..c5ad288 100644
--- a/src/gpgpu-sim/gpu-misc.cc
+++ b/src/gpgpu-sim/gpu-misc.cc
@@ -80,17 +80,3 @@ unsigned int LOGB2( unsigned int v ) {
return r;
}
-
-unsigned int MAX2NUM( unsigned int a, unsigned int b ) {
- if (a > b) {
- return a;
- } else
- return b;
-}
-
-unsigned int MIN2NUM( unsigned int a, unsigned int b ) {
- if (a < b) {
- return a;
- } else
- return b;
-}
diff --git a/src/gpgpu-sim/gpu-misc.h b/src/gpgpu-sim/gpu-misc.h
index ffe316b..57f991a 100644
--- a/src/gpgpu-sim/gpu-misc.h
+++ b/src/gpgpu-sim/gpu-misc.h
@@ -67,30 +67,12 @@
#ifndef GPU_MISC_H
#define GPU_MISC_H
-#define CONSTC 100
-#define DCACHE 200
-#define TEXTC 300
-#define SHD_CACHE_TAG(x,shdr) ((x) & (~((unsigned long long int)shdr->m_L1D->line_sz - 1)))
-#define SHD_TEXCACHE_TAG(x,shdr) ((x) & (~((unsigned long long int)shdr->m_L1T->line_sz - 1)))
-#define SHD_CONSTCACHE_TAG(x,shdr) ((x) & (~((unsigned long long int)shdr->m_L1C->line_sz - 1)))
-#define CACHE_TAG_OF(x,cache) ((x) & (~((unsigned long long int)cache->line_sz - 1)))
-#define CACHE_TAG_OF_64(x) ((x) & (~((unsigned long long int)64 - 1)))
-
-#define ispowerof2(x) ((((x) - 1) & (x)) == 0)
-#define powerof2(x) (1 << (x))
-
//enables a verbose printout of all L1 cache misses and all MSHR status changes
//good for a single shader configuration
#define DEBUGL1MISS 0
unsigned int LOGB2( unsigned int v );
-unsigned int MAX2NUM( unsigned int a, unsigned int b );
-
-unsigned int MIN2NUM( unsigned int a, unsigned int b );
-
-
-#define gs_max2(a,b) (((a)>(b))?(a):(b))
#define gs_min2(a,b) (((a)<(b))?(a):(b))
#define min3(x,y,z) (((x)<(y) && (x)<(z))?(x):(gs_min2((y),(z))))
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 8114b9e..dc76f53 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -1074,18 +1074,18 @@ void shader_core_ctx::fill_shd_L1_with_new_line(mem_fetch * mf)
// When the data arrives, it flags all the appropriate MSHR
// entries accordingly (by checking the address in each entry )
if (mf->mshr->isinst()) {
- shd_cache_fill(m_L1I,mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1I->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
m_warp[mf->mshr->get_warp_id()].clear_imiss_pending();
delete mf->mshr;
mf->mshr=NULL;
} else {
m_mshr_unit->mshr_return_from_mem(mf->mshr);
if (mf->mshr->istexture())
- shd_cache_fill(m_L1T,mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1T->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
else if (mf->mshr->isconst())
- shd_cache_fill(m_L1C,mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1C->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
else if (!m_config->gpgpu_no_dl1)
- shd_cache_fill(m_L1D,mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1D->shd_cache_fill(mf->addr,gpu_sim_cycle+gpu_tot_sim_cycle);
}
freed_read_mfs++;
delete mf;
@@ -1189,10 +1189,10 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
///////////////////////////////////////////////////////////////////////////////////////////
// wrapper code to to create an illusion of a memory controller with L2 cache.
-//#define DEBUG_PARTIAL_WRITES
void memory_partition_unit::push( mem_fetch* req, unsigned long long cycle )
{
if (req) {
+ m_request_tracker.insert(req);
rop_delay_t r;
r.req = req;
r.ready_cycle = cycle + 115; // Add 115*4=460 delay cycles
@@ -1209,12 +1209,11 @@ void memory_partition_unit::push( mem_fetch* req, unsigned long long cycle )
time_vector_update(mf->request_uid ,MR_DRAMQ,gpu_sim_cycle+gpu_tot_sim_cycle,mf->type ) ;
}
m_stats->memlatstat_icnt2mem_pop(mf);
- request_tracker_insert(mf);
if (m_config->gpgpu_cache_dl2_opt) {
if (m_config->gpgpu_l2_readoverwrite && mf->m_write)
- cbtoL2writequeue->push(mf,gpu_sim_cycle);
+ m_icnt2cache_write_queue->push(mf,gpu_sim_cycle);
else
- cbtoL2queue->push(mf,gpu_sim_cycle);
+ m_icnt2cache_queue->push(mf,gpu_sim_cycle);
m_accessLocality->access(mf);
if (mf->mshr) mf->mshr->set_status(IN_CBTOL2QUEUE);
} else {
@@ -1228,7 +1227,7 @@ mem_fetch* memory_partition_unit::pop()
{
mem_fetch* mf;
if (m_config->gpgpu_cache_dl2_opt) {
- mf = L2c_pop(m_dram);
+ mf = L2tocbqueue->pop(gpu_sim_cycle);
if (mf && mf->mshr && mf->mshr->isatomic() ) {
dram_callback_t &cb = mf->mshr->get_atomic_callback();
cb.function(cb.instruction, cb.thread);
@@ -1241,7 +1240,7 @@ mem_fetch* memory_partition_unit::pop()
cb.function(cb.instruction, cb.thread);
}
}
- request_tracker_erase(mf);
+ m_request_tracker.erase(mf);
return mf;
}
@@ -1258,25 +1257,27 @@ mem_fetch* memory_partition_unit::top()
void memory_partition_unit::issueCMD()
{
- mem_fetch* mf_top = m_dram->top();
- if (mf_top) {
- if (mf_top->type == DUMMY_READ) {
- m_dram->pop();
- free(mf_top);
- freed_dummy_read_mfs++;
- return;
- }
- }
if (m_config->gpgpu_cache_dl2_opt) {
- L2c_get_dram_output();
+ // pop completed memory request from dram and push it to dram-to-L2 queue
+ if ( !(dramtoL2queue->full() || dramtoL2writequeue->full()) ) {
+ mem_fetch* mf = m_dram->pop();
+ if (mf) {
+ if (m_config->gpgpu_l2_readoverwrite && mf->m_write)
+ dramtoL2writequeue->push(mf,gpu_sim_cycle);
+ else
+ dramtoL2queue->push(mf,gpu_sim_cycle);
+ if (mf->mshr)
+ mf->mshr->set_status(IN_DRAMTOL2QUEUE);
+ }
+ }
} else {
if ( m_dram->returnq_full() )
return;
mem_fetch* mf = m_dram->pop();
- assert (mf_top==mf );
if (mf) {
m_dram->returnq_push(mf,gpu_sim_cycle);
- if (mf->mshr) mf->mshr->set_status(IN_DRAMRETURN_Q);
+ if (mf->mshr)
+ mf->mshr->set_status(IN_DRAMRETURN_Q);
}
}
m_dram->issueCMD();
@@ -1413,18 +1414,18 @@ void gpgpu_sim::gpu_sim_loop()
if (gpgpu_flush_cache) {
int all_threads_complete = 1 ;
for (unsigned i=0;i<m_n_shader;i++) {
- if (m_sc[i]->get_not_completed() == 0) {
+ if (m_sc[i]->get_not_completed() == 0)
m_sc[i]->cache_flush();
- } else {
+ else
all_threads_complete = 0 ;
- }
}
if (all_threads_complete) {
- printf("Flushed L1 caches...\n");
+ printf("Flushed L2 caches...\n");
if (m_memory_config->gpgpu_cache_dl2_opt) {
int dlc = 0;
for (unsigned i=0;i<m_n_mem;i++) {
- dlc = m_memory_partition_unit[i]->L2c_cache_flush();
+ dlc = m_memory_partition_unit[i]->flushL2();
+ assert (dlc == 0); // need to model actual writes to DRAM here
printf("Dirty lines flushed from L2 %d is %d\n", i, dlc );
}
}
@@ -1547,6 +1548,7 @@ void gpgpu_sim::dump_pipeline( int mask, int s, int m ) const
printf("DRAM / memory controller %u:\n", i);
if(mask&0x100000) m_memory_partition_unit[i]->print_stat(stdout);
if(mask&0x1000000) m_memory_partition_unit[i]->visualize();
+ if(mask&0x10000000) m_memory_partition_unit[i]->print(stdout);
if(m != -1) {
break;
}
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index cbed2e9..0bf8af6 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -296,7 +296,7 @@ void memory_partition_unit::set_stats( class memory_stats_t *stats )
void memory_partition_unit::cache_cycle()
{
- L2c_process_dram_output(); // pop from dram
+ process_dram_output(); // pop from dram
L2c_push_miss_to_dram(); // push to dram
L2c_service_mem_req(); // pop(push) from(to) icnt2l2(l2toicnt) queues; service l2 requests
if (m_config->gpgpu_cache_dl2_opt) { // L2 cache enabled
@@ -307,13 +307,13 @@ void memory_partition_unit::cache_cycle()
unsigned memory_partition_unit::L2c_get_linesize()
{
- return L2cache->line_sz;
+ return m_L2cache->get_line_sz();
}
bool memory_partition_unit::full() const
{
if (m_config->gpgpu_cache_dl2_opt) {
- return cbtoL2queue->full() || cbtoL2writequeue->full();
+ return m_icnt2cache_queue->full() || m_icnt2cache_write_queue->full();
} else {
return( m_config->gpgpu_dram_sched_queue_size && m_dram->full() );
}
@@ -330,16 +330,15 @@ memory_partition_unit::memory_partition_unit( unsigned partition_id, struct memo
m_stats=NULL;
m_dram = new dram_t(m_id, m_config);
- char L2c_name[32];
- snprintf(L2c_name, 32, "L2_%03d", m_id);
-
if( m_config->gpgpu_cache_dl2_opt ) {
- L2cache = shd_cache_create(L2c_name,m_config->gpgpu_cache_dl2_opt, 16, ~addrdec_mask[CHIP], write_through);
- m_mshr = new L2c_mshr(L2cache->line_sz);
- m_missTracker = new L2c_miss_tracker(L2cache->line_sz);
- m_accessLocality = new L2c_access_locality(L2cache->line_sz);
+ 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_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());
} else {
- L2cache=NULL;
+ m_L2cache=NULL;
m_mshr=NULL;
m_missTracker=NULL;
m_accessLocality=NULL;
@@ -359,19 +358,18 @@ memory_partition_unit::memory_partition_unit( unsigned partition_id, struct memo
&L2c_dm_L2_length, &L2c_dm_L2w_length, &L2c_L2_cb_length,
&L2c_L2_cb_minlength, &L2c_L2_dm_minlength );
//(<name>,<latency>,<min_length>,<max_length>)
- cbtoL2queue = new fifo_pipeline<mem_fetch>("cbtoL2queue", 0,L2c_cb_L2_length, gpu_sim_cycle);
- cbtoL2writequeue = new fifo_pipeline<mem_fetch>("cbtoL2writequeue", 0,L2c_cb_L2w_length, gpu_sim_cycle);
+ m_icnt2cache_queue = new fifo_pipeline<mem_fetch>("cbtoL2queue", 0,L2c_cb_L2_length, gpu_sim_cycle);
+ m_icnt2cache_write_queue = new fifo_pipeline<mem_fetch>("cbtoL2writequeue", 0,L2c_cb_L2w_length, gpu_sim_cycle);
L2todramqueue = new fifo_pipeline<mem_fetch>("L2todramqueue", L2c_L2_dm_minlength, L2c_L2_dm_length, gpu_sim_cycle);
dramtoL2queue = new fifo_pipeline<mem_fetch>("dramtoL2queue", 0,L2c_dm_L2_length, gpu_sim_cycle);
dramtoL2writequeue = new fifo_pipeline<mem_fetch>("dramtoL2writequeue",0,L2c_dm_L2w_length, gpu_sim_cycle);
L2tocbqueue = new fifo_pipeline<mem_fetch>("L2tocbqueue", L2c_L2_cb_minlength, L2c_L2_cb_length, gpu_sim_cycle);
L2todram_wbqueue = new fifo_pipeline<mem_fetch>("L2todram_wbqueue", L2c_L2_dm_minlength, L2c_L2_dm_minlength + m_config->gpgpu_dram_sched_queue_size + L2c_dm_L2_length, gpu_sim_cycle);
- L2request = NULL;
L2dramout = NULL;
wb_addr=-1;
if (m_config->gpgpu_cache_dl2_opt && 1) {
- cbtol2_Dist = StatCreate("cbtoL2",1, cbtoL2queue->get_max_len());
- cbtoL2wr_Dist = StatCreate("cbtoL2write",1, cbtoL2writequeue->get_max_len());
+ cbtol2_Dist = StatCreate("cbtoL2",1, m_icnt2cache_queue->get_max_len());
+ cbtoL2wr_Dist = StatCreate("cbtoL2write",1, m_icnt2cache_write_queue->get_max_len());
L2tocb_Dist = StatCreate("L2tocb",1, L2tocbqueue->get_max_len());
dramtoL2_Dist = StatCreate("dramtoL2",1, dramtoL2queue->get_max_len());
dramtoL2wr_Dist = StatCreate("dramtoL2write",1, dramtoL2writequeue->get_max_len());
@@ -388,83 +386,49 @@ memory_partition_unit::memory_partition_unit( unsigned partition_id, struct memo
}
}
-mem_fetch* memory_partition_unit::L2c_pop( dram_t *dram_p )
-{
- assert(dram_p->m_memory_partition_unit != NULL);
- memory_partition_unit *p_L2c = reinterpret_cast<memory_partition_unit*>(dram_p->m_memory_partition_unit);
-
- mem_fetch *mf;
- mf = p_L2c->L2tocbqueue->pop(gpu_sim_cycle);
-
- return mf;
-}
-
-// service memory request in icnt-to-L2 queue, writing to L2 as necessary
-// (if L2 writeback miss, writeback to memory)
void memory_partition_unit::L2c_service_mem_req()
{
- if (!L2request) {
- //if not servicing L2 cache request..
- L2request = cbtoL2queue->pop(gpu_sim_cycle); //..then get one
- if (!L2request)
- L2request = cbtoL2writequeue->pop(gpu_sim_cycle);
- }
-
- mem_fetch* mf = L2request;
-
- if (!mf) return;
-
+ // service memory request in icnt-to-L2 queue, writing to L2 as necessary
+ if( L2tocbqueue->full() || L2todramqueue->full() )
+ return;
+ mem_fetch* mf = m_icnt2cache_queue->pop(gpu_sim_cycle);
+ if( !mf )
+ mf = m_icnt2cache_write_queue->pop(gpu_sim_cycle);
+ if( !mf )
+ return;
switch (mf->type) {
case RD_REQ:
case WT_REQ: {
- shd_cache_line_t *hit_cacheline = shd_cache_access(L2cache,
- mf->addr,
- 4, mf->m_write,
- gpu_sim_cycle);
-
- if (hit_cacheline || m_config->l2_ideal) { //L2 Cache Hit; reads are sent as a single command and need to be stored
- if (!mf->m_write) { //L2 Cache Read
- if ( L2tocbqueue->full() ) {
- L2cache->access--;
- } else {
- mf->type = REPLY_DATA;
- L2tocbqueue->push(mf,gpu_sim_cycle);
- // at this point, should first check if earlier L2 miss is ready to be serviced
- // if so, service earlier L2 miss first
- L2request = NULL; //finished servicing
- m_stats->L2_read_hit++;
- m_stats->memlatstat_icnt2sh_push(mf);
- if (mf->mshr) mf->mshr->set_status(IN_L2TOCBQUEUE_HIT);
- }
- } else { //L2 Cache Write aka servicing L1 Writeback
- L2request = NULL;
+ address_type rep_block;
+ enum cache_request_status status = m_L2cache->access( mf->addr, 4, mf->m_write, gpu_sim_cycle, &rep_block);
+ if( (status==HIT) || m_config->l2_ideal ) {
+ mf->type = REPLY_DATA;
+ L2tocbqueue->push(mf,gpu_sim_cycle);
+ if (!mf->m_write) {
+ m_stats->L2_read_hit++;
+ m_stats->memlatstat_icnt2sh_push(mf);
+ if (mf->mshr)
+ mf->mshr->set_status(IN_L2TOCBQUEUE_HIT);
+ } else {
m_stats->L2_write_hit++;
freed_L1write_mfs++;
- free(mf); //writeback from L1 successful
gpgpu_n_processed_writes++;
}
} else {
- // L2 Cache Miss; issue commands accordingly
- if ( L2todramqueue->full() ) {
- L2cache->miss--;
- L2cache->access--;
- } else {
- // if a miss hit the mshr, that means there is another inflight request for the same data
- // this miss just need to access the cache later when this request is serviced
- bool mshr_hit = m_mshr->new_miss(mf);
- if (not mshr_hit) {
- if (!mf->m_write) {
- L2todramqueue->push(mf,gpu_sim_cycle);
- } else {
- // if request is writeback from L1 and misses,
- // then redirect mf writes to dram (no write allocate)
- mf->nbytes_L2 = mf->nbytes_L1 - READ_PACKET_SIZE;
- L2todramqueue->push(mf,gpu_sim_cycle);
- }
+ // L2 Cache Miss
+ // if a miss hits in the mshr, that means there is another inflight request for the same data
+ // this miss just need to access the cache later when this request is serviced
+ bool mshr_hit = m_mshr->new_miss(mf);
+ if (not mshr_hit) {
+ if (mf->m_write) {
+ // if request is writeback from L1 and misses,
+ // then redirect mf writes to dram (no write allocate)
+ mf->nbytes_L2 = mf->nbytes_L1 - READ_PACKET_SIZE;
}
- if (mf->mshr) mf->mshr->set_status(IN_L2TODRAMQUEUE);
- L2request = NULL;
+ L2todramqueue->push(mf,gpu_sim_cycle);
}
+ if (mf->mshr)
+ mf->mshr->set_status(IN_L2TODRAMQUEUE);
}
}
break;
@@ -477,7 +441,6 @@ void memory_partition_unit::L2c_push_miss_to_dram()
{
if ( m_config->gpgpu_dram_sched_queue_size && m_dram->full() )
return;
-
mem_fetch* mf = L2todram_wbqueue->pop(gpu_sim_cycle); //prioritize writeback
if (!mf) mf = L2todramqueue->pop(gpu_sim_cycle);
if (mf) {
@@ -492,27 +455,9 @@ void memory_partition_unit::L2c_push_miss_to_dram()
}
}
-// pop completed memory request from dram and push it to dram-to-L2 queue
-void memory_partition_unit::L2c_get_dram_output ()
-{
- mem_fetch* mf;
- mem_fetch* mf_top;
- if ( dramtoL2queue->full() || dramtoL2writequeue->full() ) return;
- mf_top = m_dram->top();
- mf = m_dram->pop();
- assert (mf_top==mf );
- if (mf) {
- if (m_config->gpgpu_l2_readoverwrite && mf->m_write)
- dramtoL2writequeue->push(mf,gpu_sim_cycle);
- else
- dramtoL2queue->push(mf,gpu_sim_cycle);
- if (mf->mshr) mf->mshr->set_status(IN_DRAMTOL2QUEUE);
- }
-}
-
// service memory request in dramtoL2queue, writing to L2 as necessary
// (may cause cache eviction and subsequent writeback)
-void memory_partition_unit::L2c_process_dram_output()
+void memory_partition_unit::process_dram_output()
{
if (L2dramout == NULL) {
// pop from mshr chain if it is not empty, otherwise, pop a new cacheline from dram output queue
@@ -521,11 +466,10 @@ void memory_partition_unit::L2c_process_dram_output()
m_mshr->mshr_chain_pop();
} else {
L2dramout = dramtoL2queue->pop(gpu_sim_cycle);
- if (!L2dramout) L2dramout = dramtoL2writequeue->pop(gpu_sim_cycle);
-
+ if (!L2dramout)
+ L2dramout = dramtoL2writequeue->pop(gpu_sim_cycle);
if (L2dramout != NULL) {
m_mshr->miss_serviced(L2dramout);
-
if (m_mshr->mshr_chain_empty() == false) { // possible if this is a L2 writeback
L2dramout = m_mshr->mshr_chain_top();
m_mshr->mshr_chain_pop();
@@ -533,47 +477,45 @@ void memory_partition_unit::L2c_process_dram_output()
}
}
}
-
mem_fetch* mf = L2dramout;
if (mf) {
if (!mf->m_write) { //service L2 read miss
-
// it is a pre-fill dramout mf
if (wb_addr == (unsigned long long int)-1) {
- if ( L2tocbqueue->full() ) goto RETURN;
-
- if (mf->mshr) mf->mshr->set_status(IN_L2TOCBQUEUE_MISS);
-
+ if ( L2tocbqueue->full() ) {
+ assert (L2dramout || wb_addr == (unsigned long long int)-1);
+ return;
+ }
+ if (mf->mshr)
+ mf->mshr->set_status(IN_L2TOCBQUEUE_MISS);
//only transfer across icnt once the whole line has been received by L2 cache
mf->type = REPLY_DATA;
L2tocbqueue->push(mf,gpu_sim_cycle);
-
- shd_cache_line_t *fetch_line_exist = shd_cache_probe(L2cache, mf->addr);
- if (fetch_line_exist == NULL) {
- wb_addr = L2_shd_cache_fill(L2cache, mf->addr, gpu_sim_cycle );
- }
+ wb_addr = m_L2cache->shd_cache_fill(mf->addr, gpu_sim_cycle);
}
// only perform a write on cache eviction (write-back policy)
// it is the 1st or nth time trial to writeback
if (wb_addr != (unsigned long long int)-1) {
// performing L2 writeback (no false sharing for memory-side cache)
- int wb_succeed = L2c_write_back(wb_addr, L2cache->line_sz);
- if (!wb_succeed) goto RETURN; //try again next cycle
+ int wb_succeed = L2c_write_back(wb_addr, m_L2cache->get_line_sz());
+ if (!wb_succeed) {
+ assert (L2dramout || wb_addr == (unsigned long long int)-1);
+ return;
+ }
}
-
m_missTracker->miss_serviced(mf);
L2dramout = NULL;
wb_addr = -1;
} else { //service L2 write miss
m_missTracker->miss_serviced(mf);
freed_L2write_mfs++;
- free(mf);
+ m_request_tracker.erase(mf);
+ delete mf;
gpgpu_n_processed_writes++;
L2dramout = NULL;
wb_addr = -1;
}
}
- RETURN:
assert (L2dramout || wb_addr == (unsigned long long int)-1);
}
@@ -599,36 +541,37 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi
return true;
}
-unsigned int memory_partition_unit::L2c_cache_flush()
-{
- shd_cache_t *cp = L2cache;
- int dirty_lines_flushed = 0 ;
- for (unsigned i = 0; i < cp->nset * cp->assoc ; i++) {
- if ( (cp->lines[i].status & (DIRTY|VALID)) == (DIRTY|VALID) ) {
- dirty_lines_flushed++;
- }
- cp->lines[i].status &= ~VALID;
- cp->lines[i].status &= ~DIRTY;
- }
- return dirty_lines_flushed;
-}
-
void memory_partition_unit::L2c_print_cache_stat(unsigned &accesses, unsigned &misses) const
{
FILE *fp = stdout;
- shd_cache_print(L2cache,fp,accesses,misses);
+ m_L2cache->shd_cache_print(fp,accesses,misses);
m_mshr->print_stat(fp);
m_missTracker->print_stat(fp);
m_accessLocality->print_stat(fp, false);
}
+void memory_partition_unit::print( FILE *fp ) const
+{
+ if( !m_request_tracker.empty() ) {
+ fprintf(fp,"Memory Parition %u: pending memory requests:\n", m_id);
+ for( std::set<mem_fetch*>::const_iterator r=m_request_tracker.begin(); r != m_request_tracker.end(); ++r ) {
+ mem_fetch *mf = *r;
+ if( mf )
+ mf->print(fp);
+ else
+ fprintf(fp," <NULL mem_fetch?>\n");
+ }
+ }
+ m_dram->print(fp);
+}
+
void memory_partition_unit::L2c_update_stat()
{
unsigned i=m_id;
- if (cbtoL2queue->get_length() > m_stats->L2_cbtoL2length[i])
- m_stats->L2_cbtoL2length[i] = cbtoL2queue->get_length();
- if (cbtoL2writequeue->get_length() > m_stats->L2_cbtoL2writelength[i])
- m_stats->L2_cbtoL2writelength[i] = cbtoL2writequeue->get_length();
+ if (m_icnt2cache_queue->get_length() > m_stats->L2_cbtoL2length[i])
+ m_stats->L2_cbtoL2length[i] = m_icnt2cache_queue->get_length();
+ if (m_icnt2cache_write_queue->get_length() > m_stats->L2_cbtoL2writelength[i])
+ m_stats->L2_cbtoL2writelength[i] = m_icnt2cache_write_queue->get_length();
if (L2tocbqueue->get_length() > m_stats->L2_L2tocblength[i])
m_stats->L2_L2tocblength[i] = L2tocbqueue->get_length();
if (dramtoL2queue->get_length() > m_stats->L2_dramtoL2length[i])
@@ -759,8 +702,8 @@ void gpgpu_sim::L2c_print_debug()
void memory_partition_unit::L2c_log(int task)
{
if (task == SAMPLELOG) {
- StatAddSample(cbtol2_Dist, cbtoL2queue->get_length());
- StatAddSample(cbtoL2wr_Dist, cbtoL2writequeue->get_length());
+ StatAddSample(cbtol2_Dist, m_icnt2cache_queue->get_length());
+ StatAddSample(cbtoL2wr_Dist, m_icnt2cache_write_queue->get_length());
StatAddSample(L2tocb_Dist, L2tocbqueue->get_length());
StatAddSample(dramtoL2_Dist, dramtoL2queue->get_length());
StatAddSample(dramtoL2wr_Dist, dramtoL2writequeue->get_length());
@@ -777,6 +720,11 @@ void memory_partition_unit::L2c_log(int task)
}
}
+unsigned memory_partition_unit::flushL2()
+{
+ return m_L2cache->flush();
+}
+
void gpgpu_sim::L2c_latency_log_dump()
{
for (unsigned i=0;i<m_n_mem;i++)
@@ -785,8 +733,8 @@ void gpgpu_sim::L2c_latency_log_dump()
void memory_partition_unit::L2c_latency_log_dump()
{
- printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(cbtoL2queue->get_lat_stat());
- printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(cbtoL2writequeue->get_lat_stat());
+ printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(m_icnt2cache_queue->get_lat_stat());
+ printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(m_icnt2cache_write_queue->get_lat_stat());
printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(L2tocbqueue->get_lat_stat());
printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(dramtoL2queue->get_lat_stat());
printf ("(LOGB2)Latency DRAM[%u] ",m_id); StatDisp(dramtoL2writequeue->get_lat_stat());
@@ -799,12 +747,3 @@ bool memory_partition_unit::busy() const
return !m_request_tracker.empty();
}
-void memory_partition_unit::request_tracker_insert(class mem_fetch *mf)
-{
- m_request_tracker.insert(mf);
-}
-
-void memory_partition_unit::request_tracker_erase(class mem_fetch *mf)
-{
- m_request_tracker.erase(mf);
-}
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index 55202ee..b2bafb2 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -174,7 +174,7 @@ public:
void cache_cycle();
- bool has_cache() { return L2cache != NULL; }
+ bool has_cache() { return m_L2cache != NULL; }
unsigned L2c_get_linesize();
bool full() const;
bool busy() const;
@@ -186,11 +186,11 @@ public:
void visualizer_print( gzFile visualizer_file );
void L2c_latency_log_dump();
void L2c_log(int task);
- unsigned L2c_cache_flush();
+ unsigned flushL2();
void L2c_print_cache_stat(unsigned &accesses, unsigned &misses) const;
- unsigned get_cbtoL2queue_length() const { return cbtoL2queue->get_length(); }
- unsigned get_cbtoL2writequeue_length() const { return cbtoL2writequeue->get_length(); }
+ unsigned get_cbtoL2queue_length() const { return m_icnt2cache_queue->get_length(); }
+ unsigned get_cbtoL2writequeue_length() const { return m_icnt2cache_write_queue->get_length(); }
unsigned get_dramtoL2queue_length() const { return dramtoL2queue->get_length(); }
unsigned get_dramtoL2writequeue_length() const { return dramtoL2writequeue->get_length(); }
unsigned get_L2todramqueue_length() const { return L2todramqueue->get_length(); }
@@ -201,14 +201,9 @@ public:
void visualize() const { m_dram->visualize(); }
unsigned dram_que_length() const { return m_dram->que_length(); }
void queue_latency_log_dump( FILE *fp ) { m_dram->queue_latency_log_dump(fp); }
- void print( FILE *fp ) { m_dram->print(fp); }
+ void print( FILE *fp ) const;
private:
- void request_tracker_insert(class mem_fetch *mf);
- void request_tracker_erase(class mem_fetch *mf);
-
- // pop completed memory request from dram and push it to dram-to-L2 queue
- void L2c_get_dram_output();
// service memory request in icnt-to-L2 queue, writing to L2 as necessary
// (if L2 writeback miss, writeback to memory)
@@ -219,13 +214,10 @@ private:
// service memory request in dramtoL2queue, writing to L2 as necessary
// (may cause cache eviction and subsequent writeback)
- void L2c_process_dram_output();
+ void process_dram_output();
bool L2c_write_back( unsigned long long int addr, int bsize );
- // probe L2 cache for fullness
- struct mem_fetch* L2c_pop( dram_t *dram_p );
-
void L2c_init_stat(unsigned n_mem);
void L2c_update_stat();
void L2c_print_debug();
@@ -234,7 +226,7 @@ private:
unsigned m_id;
struct memory_config *m_config;
class dram_t *m_dram;
- struct shd_cache_t *L2cache;
+ class cache_t *m_L2cache;
// model delay of ROP units with a fixed latency
struct rop_delay_t
@@ -245,15 +237,13 @@ private:
std::queue<rop_delay_t> m_rop;
// these are various FIFOs between units within a memory partition
- fifo_pipeline<mem_fetch> *cbtoL2queue;
- fifo_pipeline<mem_fetch> *cbtoL2writequeue;
+ fifo_pipeline<mem_fetch> *m_icnt2cache_queue;
+ fifo_pipeline<mem_fetch> *m_icnt2cache_write_queue;
fifo_pipeline<mem_fetch> *dramtoL2queue;
fifo_pipeline<mem_fetch> *dramtoL2writequeue;
fifo_pipeline<mem_fetch> *L2todramqueue;
fifo_pipeline<mem_fetch> *L2todram_wbqueue;
- fifo_pipeline<mem_fetch> *L2tocbqueue;
-
- mem_fetch *L2request; //request currently being serviced by the L2 Cache
+ fifo_pipeline<mem_fetch> *L2tocbqueue; // L2 cache hit response queue
L2c_mshr *m_mshr; // mshr model
L2c_miss_tracker *m_missTracker; // tracker observing for redundant misses
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 99a1e58..58ed2cd 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -104,3 +104,9 @@ mem_fetch::mem_fetch( unsigned long long int addr,
mf->type = type;
mf->pc = pc;
}
+
+void mem_fetch::print( FILE *fp ) const
+{
+ fprintf(fp," mf: uid=%6u, addr=0x%08llx, sid=%u, wid=%u, pc=0x%04x, %s, bank=%u\n",
+ request_uid, addr, sid, wid, pc, (m_write?"write":"read "), bank);
+}
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index 7196690..9e9ff9a 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -76,7 +76,6 @@ enum mf_type {
WT_REQ,
REPLY_DATA, // send to shader
L2_WTBK_DATA,
- DUMMY_READ, //used in write mask
N_MF_TYPE
};
@@ -111,6 +110,8 @@ public:
enum mf_type type,
address_type pc );
+ void print( FILE *fp ) const;
+
public:
unsigned request_uid;
unsigned long long int addr;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 1f2be5a..75aec7b 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -348,17 +348,17 @@ bool shader_core_ctx::pipeline_regster_empty( inst_t *reg )
void shader_core_ctx::L1cache_print( FILE *fp, unsigned &total_accesses, unsigned &total_misses) const
{
- shd_cache_print(m_L1D,fp,total_accesses,total_misses);
+ m_L1D->shd_cache_print(fp,total_accesses,total_misses);
}
void shader_core_ctx::L1texcache_print( FILE *fp, unsigned &total_accesses, unsigned &total_misses) const
{
- shd_cache_print(m_L1T,fp,total_accesses,total_misses);
+ m_L1T->shd_cache_print(fp,total_accesses,total_misses);
}
void shader_core_ctx::L1constcache_print( FILE *fp, unsigned &total_accesses, unsigned &total_misses) const
{
- shd_cache_print(m_L1C,fp,total_accesses,total_misses);
+ m_L1C->shd_cache_print(fp,total_accesses,total_misses);
}
std::list<unsigned> shader_core_ctx::get_regs_written( const inst_t &fvt ) const
@@ -438,21 +438,15 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
char L1I_name[STRSIZE];
snprintf(L1D_name, STRSIZE, "L1D_%03d", m_sid);
- m_L1D = shd_cache_create(L1D_name,m_config->gpgpu_cache_dl1_opt,1,0,m_config->gpgpu_cache_wt_through?write_through:write_back);
- shd_cache_bind_logger(m_L1D, m_sid, get_shader_normal_cache_id());
-
snprintf(L1T_name, STRSIZE, "L1T_%03d", m_sid);
- m_L1T = shd_cache_create(L1T_name,m_config->gpgpu_cache_texl1_opt,1,0, no_writes );
- shd_cache_bind_logger(m_L1T, m_sid, get_shader_texture_cache_id());
- ptx_set_tex_cache_linesize(m_L1T->line_sz);
-
snprintf(L1C_name, STRSIZE, "L1C_%03d", m_sid);
- m_L1C = shd_cache_create(L1C_name,m_config->gpgpu_cache_constl1_opt,1,0, no_writes );
- shd_cache_bind_logger(m_L1C, m_sid, get_shader_constant_cache_id());
-
snprintf(L1I_name, STRSIZE, "L1I_%03d", m_sid);
- m_L1I = shd_cache_create(L1I_name,m_config->gpgpu_cache_il1_opt,1,0, no_writes );
- shd_cache_bind_logger(m_L1D, m_sid, get_shader_instruction_cache_id());
+ 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_L1I = new cache_t(L1I_name,m_config->gpgpu_cache_il1_opt, 0,no_writes, m_sid,get_shader_instruction_cache_id());
+ ptx_set_tex_cache_linesize(m_L1T->get_line_sz());
m_mshr_unit = new mshr_shader_unit(m_config);
m_pdom_warp = new pdom_warp_ctx_t*[config->max_warps_per_shader];
@@ -896,9 +890,9 @@ void pdom_warp_ctx_t::print (FILE *fout) const
void shader_core_ctx::new_cache_window()
{
- shd_cache_new_window(m_L1D);
- shd_cache_new_window(m_L1T);
- shd_cache_new_window(m_L1C);
+ m_L1D->shd_cache_new_window();
+ m_L1T->shd_cache_new_window();
+ m_L1C->shd_cache_new_window();
}
void shader_core_ctx::fetch_mimd()
@@ -1166,10 +1160,10 @@ void shader_core_ctx::fetch_new()
address_type ppc = pc + PROGRAM_MEM_START;
address_type wb=0;
unsigned nbytes=16;
- unsigned offset_in_block = pc & (m_L1I->line_sz-1);
- if( (offset_in_block+nbytes) > m_L1I->line_sz )
- nbytes = (m_L1I->line_sz-offset_in_block);
- enum cache_request_status status = shd_cache_access_new( m_L1I, (unsigned long long)pc, nbytes, 0, gpu_sim_cycle, &wb );
+ unsigned offset_in_block = pc & (m_L1I->get_line_sz()-1);
+ if( (offset_in_block+nbytes) > m_L1I->get_line_sz() )
+ nbytes = (m_L1I->get_line_sz()-offset_in_block);
+ enum cache_request_status status = m_L1I->access( (unsigned long long)pc, nbytes, 0, gpu_sim_cycle, &wb );
if( status != HIT ) {
unsigned req_size = READ_PACKET_SIZE;
if( m_gpu->fq_has_buffer(ppc, req_size, false, m_sid) ) {
@@ -1852,19 +1846,18 @@ void shader_core_ctx::memory_const_process_warp()
line_size_based_tag_func,
CONSTANT_MEM_PATH,
1, //warp parts
- m_L1C->line_sz, false, //no broadcast limit.
+ m_L1C->get_line_sz(), false, //no broadcast limit.
accessq);
//do cache checks here for each request (non-physical), could be done later for more accurate timing of cache accesses, but probably uneccesary;
for (unsigned i = qbegin; i < accessq.size(); i++) {
if ( accessq[i].space == param_space_kernel ) {
accessq[i].cache_hit = true;
} else {
- cache_request_status status = shd_cache_access_new(m_L1C,
- accessq[i].addr,
- WORD_SIZE, //this field is ingored.
- 0, //should always be a read
- gpu_sim_cycle+gpu_tot_sim_cycle,
- NULL/*should never writeback*/);
+ cache_request_status status = m_L1C->access( accessq[i].addr,
+ WORD_SIZE, //this field is ingored.
+ 0, //should always be a read
+ gpu_sim_cycle+gpu_tot_sim_cycle,
+ NULL/*should never writeback*/);
accessq[i].cache_hit = (status == HIT);
if (m_config->gpgpu_perfect_mem) accessq[i].cache_hit = true;
if (accessq[i].cache_hit) m_stats->L1_const_miss++;
@@ -1882,17 +1875,16 @@ void shader_core_ctx::memory_texture_process_warp()
&line_size_based_tag_func,
TEXTURE_MEM_PATH,
1, //warp parts
- m_L1T->line_sz,
+ m_L1T->get_line_sz(),
false, //no broadcast limit.
accessq);
//do cache checks here for each request (non-hardware), could be done later for more accurate timing of cache accesses, but probably uneccesary;
for (unsigned i = qbegin; i < accessq.size(); i++) {
- cache_request_status status = shd_cache_access_new(m_L1T,
- accessq[i].addr,
- WORD_SIZE, //this field is ignored.
- 0, //should always be a read
- gpu_sim_cycle+gpu_tot_sim_cycle,
- NULL /*should never writeback*/);
+ cache_request_status status = m_L1T->access( accessq[i].addr,
+ WORD_SIZE, //this field is ignored.
+ 0, //should always be a read
+ gpu_sim_cycle+gpu_tot_sim_cycle,
+ NULL /*should never writeback*/);
accessq[i].cache_hit = (status == HIT);
if (m_config->gpgpu_perfect_mem) accessq[i].cache_hit = true;
if (accessq[i].cache_hit) m_stats->L1_texture_miss++;
@@ -1905,7 +1897,7 @@ void shader_core_ctx::memory_global_process_warp()
std::vector<mem_access_t> &accessq = m_memory_queue.local_global;
unsigned qbegin = accessq.size();
unsigned warp_parts = 1;
- unsigned line_size = m_L1D->line_sz;
+ unsigned line_size = m_L1D->get_line_sz();
if (m_config->gpgpu_coalesce_arch == 13) {
warp_parts = 2;
if(m_config->gpgpu_no_dl1) {
@@ -1966,7 +1958,7 @@ mem_stage_stall_type shader_core_ctx::send_mem_request(mem_access_t &access)
// If the cache told us it needed to write back a dirty line, do this now
// It is possible to do this writeback in the same cycle as the access request, this may not be realistic.
if (access.need_wb) {
- unsigned req_size = m_L1D->line_sz + WRITE_PACKET_SIZE;
+ unsigned req_size = m_L1D->get_line_sz() + WRITE_PACKET_SIZE;
if ( ! m_gpu->fq_has_buffer(access.wb_addr, req_size, true, m_sid) ) {
m_stats->gpu_stall_sh2icnt++;
return WB_ICNT_RC_FAIL;
@@ -1978,15 +1970,14 @@ mem_stage_stall_type shader_core_ctx::send_mem_request(mem_access_t &access)
access.need_wb = false;
}
- unsigned code;
mem_access_type access_type;
switch(access.space.get_type()) {
case const_space:
- case param_space_kernel: code = CONSTC; access_type = CONST_ACC_R; break;
- case tex_space: code = TEXTC; access_type = TEXTURE_ACC_R; break;
- case global_space: code = DCACHE; access_type = (access.iswrite)? GLOBAL_ACC_W: GLOBAL_ACC_R; break;
+ case param_space_kernel: access_type = CONST_ACC_R; break;
+ case tex_space: access_type = TEXTURE_ACC_R; break;
+ case global_space: access_type = (access.iswrite)? GLOBAL_ACC_W: GLOBAL_ACC_R; break;
case local_space:
- case param_space_local: code = DCACHE; access_type = (access.iswrite)? LOCAL_ACC_W: LOCAL_ACC_R; break;
+ case param_space_local: access_type = (access.iswrite)? LOCAL_ACC_W: LOCAL_ACC_R; break;
default: assert(0); break;
}
//reserve mshr
@@ -2162,12 +2153,11 @@ mem_stage_stall_type shader_core_ctx::dcache_check(mem_access_t& access)
return NO_RC_FAIL;
if (!m_config->gpgpu_no_dl1 && !m_config->gpgpu_perfect_mem) {
//check cache
- cache_request_status status = shd_cache_access_new(m_L1D,
- access.addr,
- WORD_SIZE, //this field is ignored.
- access.iswrite,
- gpu_sim_cycle+gpu_tot_sim_cycle,
- &access.wb_addr);
+ cache_request_status status = m_L1D->access( access.addr,
+ WORD_SIZE, //this field is ignored.
+ access.iswrite,
+ gpu_sim_cycle+gpu_tot_sim_cycle,
+ &access.wb_addr );
if (status == RESERVATION_FAIL) {
access.cache_checked = false;
return WB_CACHE_RSRV_FAIL;
@@ -2951,27 +2941,28 @@ void shader_core_ctx::cycle()
void shader_core_ctx::cache_flush()
{
+ m_L1D->flush();
+ // TODO: add flush 'interface' object to provide functionality commented out below
+/*
+
unsigned int i;
unsigned int set;
unsigned long long int flush_addr;
-
- shd_cache_t *cp = m_L1D;
- shd_cache_line_t *pline;
-
- for (i=0; i<cp->nset*cp->assoc; i++) {
- pline = &(cp->lines[i]);
- set = i / cp->assoc;
+ cache_t *cp = m_L1D;
+ cache_block_t *pline;
+ for (i=0; i<cp->m_nset*cp->m_assoc; i++) {
+ pline = &(cp->m_lines[i]);
+ set = i / cp->m_assoc;
if ((pline->status & (DIRTY|VALID)) == (DIRTY|VALID)) {
flush_addr = pline->addr;
-
- fq_push(flush_addr, m_L1D->line_sz, 1, NO_PARTIAL_WRITE, 0, NULL, 0, GLOBAL_ACC_W, -1);
-
+ fq_push(flush_addr, m_L1D->get_line_sz(), 1, NO_PARTIAL_WRITE, 0, NULL, 0, GLOBAL_ACC_W, -1);
pline->status &= ~VALID;
pline->status &= ~DIRTY;
} else if (pline->status & VALID) {
pline->status &= ~VALID;
}
}
+*/
}
static int *_inmatch;
@@ -3356,6 +3347,7 @@ void mshr_entry::set_status( enum mshr_status status )
req = req->m_merged_requests;
}
#if DEBUGL1MISS
+#define CACHE_TAG_OF_64(x) ((x) & (~((unsigned long long int)64 - 1)))
printf("cycle %d Addr %x %d \n",gpu_sim_cycle,CACHE_TAG_OF_64(m_addr),status);
#endif
}
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 44206af..fe6192a 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1099,9 +1099,9 @@ public:
void L1texcache_print( FILE *fp, unsigned &total_accesses, unsigned &total_misses) const;
void L1constcache_print( FILE *fp, unsigned &total_accesses, unsigned &total_misses) const;
unsigned get_n_active_cta() const { return m_n_active_cta; }
- float L1_windowed_cache_miss_rate( int x ) const { return shd_cache_windowed_cache_miss_rate(m_L1D,x); }
- float L1tex_windowed_cache_miss_rate( int x ) const { return shd_cache_windowed_cache_miss_rate(m_L1T,x); }
- float L1const_windowed_cache_miss_rate( int x ) const { return shd_cache_windowed_cache_miss_rate(m_L1C,x); }
+ float L1_windowed_cache_miss_rate( int x ) const { return m_L1D->shd_cache_windowed_cache_miss_rate(x); }
+ float L1tex_windowed_cache_miss_rate( int x ) const { return m_L1T->shd_cache_windowed_cache_miss_rate(x); }
+ float L1const_windowed_cache_miss_rate( int x ) const { return m_L1C->shd_cache_windowed_cache_miss_rate(x); }
private:
@@ -1252,10 +1252,10 @@ private:
int m_dwf_RR_k; // counter for register read pipeline
int *m_dwf_rrstage_bank_access_counter;
- shd_cache_t *m_L1I; // instruction cache
- shd_cache_t *m_L1D; // data cache (global/local memory accesses)
- shd_cache_t *m_L1T; // texture cache
- shd_cache_t *m_L1C; // constant cache
+ cache_t *m_L1I; // instruction cache
+ cache_t *m_L1D; // data cache (global/local memory accesses)
+ cache_t *m_L1T; // texture cache
+ cache_t *m_L1C; // constant cache
bool m_shader_memory_new_instruction_processed;
int m_pending_mem_access; // number of memory access to be serviced (use for W0 classification)