"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

cache.h File Reference

#include <stdio.h>
#include "host.h"
#include "misc.h"
#include "machine.h"
#include "memory.h"
#include "stats.h"

Include dependency graph for cache.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

Defines

Enumerations

Functions


Define Documentation

#define CACHE_BLK_DIRTY   0x00000002
 

Definition at line 136 of file cache.h.

Referenced by cache_access(), cache_flush(), and cache_flush_addr().

#define CACHE_BLK_VALID   0x00000001
 

Definition at line 135 of file cache.h.

Referenced by cache_access(), cache_flush(), cache_flush_addr(), and cache_probe().

#define cache_byte cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(char), now, udata)
 

Definition at line 305 of file cache.h.

#define cache_double cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(double), now, udata)
 

Definition at line 295 of file cache.h.

#define cache_dword cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(long long), now, udata)
 

Definition at line 299 of file cache.h.

#define cache_float cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(float), now, udata)
 

Definition at line 297 of file cache.h.

#define cache_half cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(short), now, udata)
 

Definition at line 303 of file cache.h.

#define CACHE_HIGHLY_ASSOC cp       ((cp)->assoc > 4)
 

Definition at line 125 of file cache.h.

Referenced by cache_create().

#define cache_word cp,
cmd,
addr,
p,
now,
udata       cache_access(cp, cmd, addr, p, sizeof(int), now, udata)
 

Definition at line 301 of file cache.h.


Enumeration Type Documentation

enum cache_policy
 

Enumeration values:
LRU 
Random 
FIFO 

Definition at line 128 of file cache.h.

00128                   {
00129   LRU,          /* replace least recently used block (perfect LRU) */
00130   Random,       /* replace a random block */
00131   FIFO          /* replace the oldest block in the set */
00132 };


Function Documentation

unsigned int cache_access struct cache_t   cp,
enum mem_cmd    cmd,
md_addr_t    addr,
void *    vp,
int    nbytes,
tick_t    now,
byte_t **    udata,
md_addr_t   repl_addr
 

Definition at line 537 of file cache.c.

References cache_t::assoc, cache_t::balloc, cache_t::blk_access_fn, cache_t::blk_mask, cache_set_t::blks, BOUND_POS, cache_t::bsize, cache_t::bus_free, byte_t, CACHE_BADDR, CACHE_BCOPY, CACHE_BINDEX, CACHE_BLK, CACHE_BLK_DIRTY, CACHE_BLK_VALID, CACHE_HASH, CACHE_MK_BADDR, CACHE_SET, CACHE_TAG, CACHE_TAGSET, fatal(), FIFO, cache_set_t::hash, cache_blk_t::hash_next, Head, cache_t::hit_latency, cache_t::hits, cache_t::hsize, cache_t::last_blk, cache_t::last_tagset, link_htab_ent(), MAX, cache_t::misses, myrand(), panic(), cache_t::policy, Random, Read, cache_blk_t::ready, cache_t::replacements, cache_t::sets, cache_blk_t::status, cache_blk_t::tag, tag, unlink_htab_ent(), update_way_list(), cache_blk_t::user_data, cache_set_t::way_head, cache_blk_t::way_next, cache_blk_t::way_prev, cache_set_t::way_tail, Write, and cache_t::writebacks.

Referenced by dcache_access_fn(), dl1_access_fn(), il1_access_fn(), ruu_commit(), ruu_issue(), and sim_main().

00545 {
00546   byte_t *p = vp;
00547   md_addr_t tag = CACHE_TAG(cp, addr);
00548   md_addr_t set = CACHE_SET(cp, addr);
00549   md_addr_t bofs = CACHE_BLK(cp, addr);
00550   struct cache_blk_t *blk, *repl;
00551   int lat = 0;
00552 
00553   /* default replacement address */
00554   if (repl_addr)
00555     *repl_addr = 0;
00556 
00557   /* check alignments */
00558   if ((nbytes & (nbytes-1)) != 0 || (addr & (nbytes-1)) != 0)
00559     fatal("cache: access error: bad size or alignment, addr 0x%08x", addr);
00560 
00561   /* access must fit in cache block */
00562   /* FIXME:
00563      ((addr + (nbytes - 1)) > ((addr & ~cp->blk_mask) + (cp->bsize - 1))) */
00564   if ((addr + nbytes) > ((addr & ~cp->blk_mask) + cp->bsize))
00565     fatal("cache: access error: access spans block, addr 0x%08x", addr);
00566 
00567   /* permissions are checked on cache misses */
00568 
00569   /* check for a fast hit: access to same block */
00570   if (CACHE_TAGSET(cp, addr) == cp->last_tagset)
00571     {
00572       /* hit in the same block */
00573       blk = cp->last_blk;
00574       goto cache_fast_hit;
00575     }
00576     
00577   if (cp->hsize)
00578     {
00579       /* higly-associativity cache, access through the per-set hash tables */
00580       int hindex = CACHE_HASH(cp, tag);
00581 
00582       for (blk=cp->sets[set].hash[hindex];
00583            blk;
00584            blk=blk->hash_next)
00585         {
00586           if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00587             goto cache_hit;
00588         }
00589     }
00590   else
00591     {
00592       /* low-associativity cache, linear search the way list */
00593       for (blk=cp->sets[set].way_head;
00594            blk;
00595            blk=blk->way_next)
00596         {
00597           if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00598             goto cache_hit;
00599         }
00600     }
00601 
00602   /* cache block not found */
00603 
00604   /* **MISS** */
00605   cp->misses++;
00606 
00607   /* select the appropriate block to replace, and re-link this entry to
00608      the appropriate place in the way list */
00609   switch (cp->policy) {
00610   case LRU:
00611   case FIFO:
00612     repl = cp->sets[set].way_tail;
00613     update_way_list(&cp->sets[set], repl, Head);
00614     break;
00615   case Random:
00616     {
00617       int bindex = myrand() & (cp->assoc - 1);
00618       repl = CACHE_BINDEX(cp, cp->sets[set].blks, bindex);
00619     }
00620     break;
00621   default:
00622     panic("bogus replacement policy");
00623   }
00624 
00625   /* remove this block from the hash bucket chain, if hash exists */
00626   if (cp->hsize)
00627     unlink_htab_ent(cp, &cp->sets[set], repl);
00628 
00629   /* blow away the last block to hit */
00630   cp->last_tagset = 0;
00631   cp->last_blk = NULL;
00632 
00633   /* write back replaced block data */
00634   if (repl->status & CACHE_BLK_VALID)
00635     {
00636       cp->replacements++;
00637 
00638       if (repl_addr)
00639         *repl_addr = CACHE_MK_BADDR(cp, repl->tag, set);
00640  
00641       /* don't replace the block until outstanding misses are satisfied */
00642       lat += BOUND_POS(repl->ready - now);
00643  
00644       /* stall until the bus to next level of memory is available */
00645       lat += BOUND_POS(cp->bus_free - (now + lat));
00646  
00647       /* track bus resource usage */
00648       cp->bus_free = MAX(cp->bus_free, (now + lat)) + 1;
00649 
00650       if (repl->status & CACHE_BLK_DIRTY)
00651         {
00652           /* write back the cache block */
00653           cp->writebacks++;
00654           lat += cp->blk_access_fn(Write,
00655                                    CACHE_MK_BADDR(cp, repl->tag, set),
00656                                    cp->bsize, repl, now+lat);
00657         }
00658     }
00659 
00660   /* update block tags */
00661   repl->tag = tag;
00662   repl->status = CACHE_BLK_VALID;       /* dirty bit set on update */
00663 
00664   /* read data block */
00665   lat += cp->blk_access_fn(Read, CACHE_BADDR(cp, addr), cp->bsize,
00666                            repl, now+lat);
00667 
00668   /* copy data out of cache block */
00669   if (cp->balloc)
00670     {
00671       CACHE_BCOPY(cmd, repl, bofs, p, nbytes);
00672     }
00673 
00674   /* update dirty status */
00675   if (cmd == Write)
00676     repl->status |= CACHE_BLK_DIRTY;
00677 
00678   /* get user block data, if requested and it exists */
00679   if (udata)
00680     *udata = repl->user_data;
00681 
00682   /* update block status */
00683   repl->ready = now+lat;
00684 
00685   /* link this entry back into the hash table */
00686   if (cp->hsize)
00687     link_htab_ent(cp, &cp->sets[set], repl);
00688 
00689   /* return latency of the operation */
00690   return lat;
00691 
00692 
00693  cache_hit: /* slow hit handler */
00694   
00695   /* **HIT** */
00696   cp->hits++;
00697 
00698   /* copy data out of cache block, if block exists */
00699   if (cp->balloc)
00700     {
00701       CACHE_BCOPY(cmd, blk, bofs, p, nbytes);
00702     }
00703 
00704   /* update dirty status */
00705   if (cmd == Write)
00706     blk->status |= CACHE_BLK_DIRTY;
00707 
00708   /* if LRU replacement and this is not the first element of list, reorder */
00709   if (blk->way_prev && cp->policy == LRU)
00710     {
00711       /* move this block to head of the way (MRU) list */
00712       update_way_list(&cp->sets[set], blk, Head);
00713     }
00714 
00715   /* tag is unchanged, so hash links (if they exist) are still valid */
00716 
00717   /* record the last block to hit */
00718   cp->last_tagset = CACHE_TAGSET(cp, addr);
00719   cp->last_blk = blk;
00720 
00721   /* get user block data, if requested and it exists */
00722   if (udata)
00723     *udata = blk->user_data;
00724 
00725   /* return first cycle data is available to access */
00726   return (int) MAX(cp->hit_latency, (blk->ready - now));
00727 
00728  cache_fast_hit: /* fast hit handler */
00729   
00730   /* **FAST HIT** */
00731   cp->hits++;
00732 
00733   /* copy data out of cache block, if block exists */
00734   if (cp->balloc)
00735     {
00736       CACHE_BCOPY(cmd, blk, bofs, p, nbytes);
00737     }
00738 
00739   /* update dirty status */
00740   if (cmd == Write)
00741     blk->status |= CACHE_BLK_DIRTY;
00742 
00743   /* this block hit last, no change in the way list */
00744 
00745   /* tag is unchanged, so hash links (if they exist) are still valid */
00746 
00747   /* get user block data, if requested and it exists */
00748   if (udata)
00749     *udata = blk->user_data;
00750 
00751   /* record the last block to hit */
00752   cp->last_tagset = CACHE_TAGSET(cp, addr);
00753   cp->last_blk = blk;
00754 
00755   /* return first cycle data is available to access */
00756   return (int) MAX(cp->hit_latency, (blk->ready - now));
00757 }

enum cache_policy cache_char2policy char    c
 

Definition at line 443 of file cache.c.

References fatal(), FIFO, and Random.

Referenced by sim_check_options().

00444 {
00445   switch (c) {
00446   case 'l': return LRU;
00447   case 'r': return Random;
00448   case 'f': return FIFO;
00449   default: fatal("bogus replacement policy, `%c'", c);
00450   }
00451 }

void cache_config struct cache_t   cp,
FILE *    stream
 

Definition at line 455 of file cache.c.

References cache_t::assoc, cache_t::bsize, FIFO, cache_t::name, cache_t::nsets, cache_t::policy, Random, and cache_t::usize.

00457 {
00458   fprintf(stream,
00459           "cache: %s: %d sets, %d byte blocks, %d bytes user data/block\n",
00460           cp->name, cp->nsets, cp->bsize, cp->usize);
00461   fprintf(stream,
00462           "cache: %s: %d-way, `%s' replacement policy, write-back\n",
00463           cp->name, cp->assoc,
00464           cp->policy == LRU ? "LRU"
00465           : cp->policy == Random ? "Random"
00466           : cp->policy == FIFO ? "FIFO"
00467           : (abort(), ""));
00468 }

struct cache_t* cache_create char *    name,
int    nsets,
int    bsize,
int    balloc,
int    usize,
int    assoc,
enum cache_policy    policy,
unsigned int(*    blk_access_fn)(enum mem_cmd cmd, md_addr_t baddr, int bsize, struct cache_blk_t *blk, tick_t now),
unsigned int    hit_latency
 

Definition at line 298 of file cache.c.

References cache_t::assoc, cache_t::balloc, cache_t::blk_access_fn, cache_t::blk_mask, cache_set_t::blks, cache_t::bsize, cache_t::bus_free, byte_t, CACHE_BINDEX, CACHE_HIGHLY_ASSOC, cache_t::data, debug(), fatal(), cache_set_t::hash, cache_t::hit_latency, cache_t::hits, cache_t::hsize, cache_t::invalidations, cache_t::last_blk, cache_t::last_tagset, link_htab_ent(), log_base2(), cache_t::misses, mystrdup(), cache_t::name, cache_t::nsets, cache_t::policy, cache_blk_t::ready, cache_t::replacements, cache_t::set_mask, cache_t::set_shift, cache_t::sets, cache_blk_t::status, cache_blk_t::tag, cache_t::tag_mask, cache_t::tag_shift, cache_t::tagset_mask, cache_blk_t::user_data, cache_t::usize, cache_set_t::way_head, cache_blk_t::way_next, cache_blk_t::way_prev, cache_set_t::way_tail, and cache_t::writebacks.

Referenced by sim_check_options().

00311 {
00312   struct cache_t *cp;
00313   struct cache_blk_t *blk;
00314   int i, j, bindex;
00315 
00316   /* check all cache parameters */
00317   if (nsets <= 0)
00318     fatal("cache size (in sets) `%d' must be non-zero", nsets);
00319   if ((nsets & (nsets-1)) != 0)
00320     fatal("cache size (in sets) `%d' is not a power of two", nsets);
00321   /* blocks must be at least one datum large, i.e., 8 bytes for SS */
00322   if (bsize < 8)
00323     fatal("cache block size (in bytes) `%d' must be 8 or greater", bsize);
00324   if ((bsize & (bsize-1)) != 0)
00325     fatal("cache block size (in bytes) `%d' must be a power of two", bsize);
00326   if (usize < 0)
00327     fatal("user data size (in bytes) `%d' must be a positive value", usize);
00328   if (assoc <= 0)
00329     fatal("cache associativity `%d' must be non-zero and positive", assoc);
00330   if ((assoc & (assoc-1)) != 0)
00331     fatal("cache associativity `%d' must be a power of two", assoc);
00332   if (!blk_access_fn)
00333     fatal("must specify miss/replacement functions");
00334 
00335   /* allocate the cache structure */
00336   cp = (struct cache_t *)
00337     calloc(1, sizeof(struct cache_t) + (nsets-1)*sizeof(struct cache_set_t));
00338   if (!cp)
00339     fatal("out of virtual memory");
00340 
00341   /* initialize user parameters */
00342   cp->name = mystrdup(name);
00343   cp->nsets = nsets;
00344   cp->bsize = bsize;
00345   cp->balloc = balloc;
00346   cp->usize = usize;
00347   cp->assoc = assoc;
00348   cp->policy = policy;
00349   cp->hit_latency = hit_latency;
00350 
00351   /* miss/replacement functions */
00352   cp->blk_access_fn = blk_access_fn;
00353 
00354   /* compute derived parameters */
00355   cp->hsize = CACHE_HIGHLY_ASSOC(cp) ? (assoc >> 2) : 0;
00356   cp->blk_mask = bsize-1;
00357   cp->set_shift = log_base2(bsize);
00358   cp->set_mask = nsets-1;
00359   cp->tag_shift = cp->set_shift + log_base2(nsets);
00360   cp->tag_mask = (1 << (32 - cp->tag_shift))-1;
00361   cp->tagset_mask = ~cp->blk_mask;
00362   cp->bus_free = 0;
00363 
00364   /* print derived parameters during debug */
00365   debug("%s: cp->hsize     = %d", cp->name, cp->hsize);
00366   debug("%s: cp->blk_mask  = 0x%08x", cp->name, cp->blk_mask);
00367   debug("%s: cp->set_shift = %d", cp->name, cp->set_shift);
00368   debug("%s: cp->set_mask  = 0x%08x", cp->name, cp->set_mask);
00369   debug("%s: cp->tag_shift = %d", cp->name, cp->tag_shift);
00370   debug("%s: cp->tag_mask  = 0x%08x", cp->name, cp->tag_mask);
00371 
00372   /* initialize cache stats */
00373   cp->hits = 0;
00374   cp->misses = 0;
00375   cp->replacements = 0;
00376   cp->writebacks = 0;
00377   cp->invalidations = 0;
00378 
00379   /* blow away the last block accessed */
00380   cp->last_tagset = 0;
00381   cp->last_blk = NULL;
00382 
00383   /* allocate data blocks */
00384   cp->data = (byte_t *)calloc(nsets * assoc,
00385                               sizeof(struct cache_blk_t) +
00386                               (cp->balloc ? (bsize*sizeof(byte_t)) : 0));
00387   if (!cp->data)
00388     fatal("out of virtual memory");
00389 
00390   /* slice up the data blocks */
00391   for (bindex=0,i=0; i<nsets; i++)
00392     {
00393       cp->sets[i].way_head = NULL;
00394       cp->sets[i].way_tail = NULL;
00395       /* get a hash table, if needed */
00396       if (cp->hsize)
00397         {
00398           cp->sets[i].hash =
00399             (struct cache_blk_t **)calloc(cp->hsize,
00400                                           sizeof(struct cache_blk_t *));
00401           if (!cp->sets[i].hash)
00402             fatal("out of virtual memory");
00403         }
00404       /* NOTE: all the blocks in a set *must* be allocated contiguously,
00405          otherwise, block accesses through SET->BLKS will fail (used
00406          during random replacement selection) */
00407       cp->sets[i].blks = CACHE_BINDEX(cp, cp->data, bindex);
00408       
00409       /* link the data blocks into ordered way chain and hash table bucket
00410          chains, if hash table exists */
00411       for (j=0; j<assoc; j++)
00412         {
00413           /* locate next cache block */
00414           blk = CACHE_BINDEX(cp, cp->data, bindex);
00415           bindex++;
00416 
00417           /* invalidate new cache block */
00418           blk->status = 0;
00419           blk->tag = 0;
00420           blk->ready = 0;
00421           blk->user_data = (usize != 0
00422                             ? (byte_t *)calloc(usize, sizeof(byte_t)) : NULL);
00423 
00424           /* insert cache block into set hash table */
00425           if (cp->hsize)
00426             link_htab_ent(cp, &cp->sets[i], blk);
00427 
00428           /* insert into head of way list, order is arbitrary at this point */
00429           blk->way_next = cp->sets[i].way_head;
00430           blk->way_prev = NULL;
00431           if (cp->sets[i].way_head)
00432             cp->sets[i].way_head->way_prev = blk;
00433           cp->sets[i].way_head = blk;
00434           if (!cp->sets[i].way_tail)
00435             cp->sets[i].way_tail = blk;
00436         }
00437     }
00438   return cp;
00439 }

unsigned int cache_flush struct cache_t   cp,
tick_t    now
 

Definition at line 803 of file cache.c.

References cache_t::blk_access_fn, cache_t::bsize, CACHE_BLK_DIRTY, CACHE_BLK_VALID, CACHE_MK_BADDR, cache_t::hit_latency, cache_t::invalidations, cache_t::last_blk, cache_t::last_tagset, cache_t::nsets, cache_t::sets, cache_blk_t::status, cache_blk_t::tag, cache_set_t::way_head, cache_blk_t::way_next, Write, and cache_t::writebacks.

00805 {
00806   int i, lat = cp->hit_latency; /* min latency to probe cache */
00807   struct cache_blk_t *blk;
00808 
00809   /* blow away the last block to hit */
00810   cp->last_tagset = 0;
00811   cp->last_blk = NULL;
00812 
00813   /* no way list updates required because all blocks are being invalidated */
00814   for (i=0; i<cp->nsets; i++)
00815     {
00816       for (blk=cp->sets[i].way_head; blk; blk=blk->way_next)
00817         {
00818           if (blk->status & CACHE_BLK_VALID)
00819             {
00820               cp->invalidations++;
00821               blk->status &= ~CACHE_BLK_VALID;
00822 
00823               if (blk->status & CACHE_BLK_DIRTY)
00824                 {
00825                   /* write back the invalidated block */
00826                   cp->writebacks++;
00827                   lat += cp->blk_access_fn(Write,
00828                                            CACHE_MK_BADDR(cp, blk->tag, i),
00829                                            cp->bsize, blk, now+lat);
00830                 }
00831             }
00832         }
00833     }
00834 
00835   /* return latency of the flush operation */
00836   return lat;
00837 }

unsigned int cache_flush_addr struct cache_t   cp,
md_addr_t    addr,
tick_t    now
 

Definition at line 842 of file cache.c.

References cache_t::blk_access_fn, cache_t::bsize, CACHE_BLK_DIRTY, CACHE_BLK_VALID, CACHE_HASH, CACHE_MK_BADDR, CACHE_SET, CACHE_TAG, cache_set_t::hash, cache_blk_t::hash_next, cache_t::hit_latency, cache_t::hsize, cache_t::invalidations, cache_t::last_blk, cache_t::last_tagset, cache_t::sets, cache_blk_t::status, cache_blk_t::tag, tag, Tail, update_way_list(), cache_set_t::way_head, cache_blk_t::way_next, Write, and cache_t::writebacks.

00845 {
00846   md_addr_t tag = CACHE_TAG(cp, addr);
00847   md_addr_t set = CACHE_SET(cp, addr);
00848   struct cache_blk_t *blk;
00849   int lat = cp->hit_latency; /* min latency to probe cache */
00850 
00851   if (cp->hsize)
00852     {
00853       /* higly-associativity cache, access through the per-set hash tables */
00854       int hindex = CACHE_HASH(cp, tag);
00855 
00856       for (blk=cp->sets[set].hash[hindex];
00857            blk;
00858            blk=blk->hash_next)
00859         {
00860           if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00861             break;
00862         }
00863     }
00864   else
00865     {
00866       /* low-associativity cache, linear search the way list */
00867       for (blk=cp->sets[set].way_head;
00868            blk;
00869            blk=blk->way_next)
00870         {
00871           if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00872             break;
00873         }
00874     }
00875 
00876   if (blk)
00877     {
00878       cp->invalidations++;
00879       blk->status &= ~CACHE_BLK_VALID;
00880 
00881       /* blow away the last block to hit */
00882       cp->last_tagset = 0;
00883       cp->last_blk = NULL;
00884 
00885       if (blk->status & CACHE_BLK_DIRTY)
00886         {
00887           /* write back the invalidated block */
00888           cp->writebacks++;
00889           lat += cp->blk_access_fn(Write,
00890                                    CACHE_MK_BADDR(cp, blk->tag, set),
00891                                    cp->bsize, blk, now+lat);
00892         }
00893       /* move this block to tail of the way (LRU) list */
00894       update_way_list(&cp->sets[set], blk, Tail);
00895     }
00896 
00897   /* return latency of the operation */
00898   return lat;
00899 }

int cache_probe struct cache_t   cp,
md_addr_t    addr
 

Definition at line 763 of file cache.c.

References CACHE_BLK_VALID, CACHE_HASH, CACHE_SET, CACHE_TAG, FALSE, cache_set_t::hash, cache_blk_t::hash_next, cache_t::hsize, cache_t::sets, cache_blk_t::status, cache_blk_t::tag, tag, TRUE, cache_set_t::way_head, and cache_blk_t::way_next.

00765 {
00766   md_addr_t tag = CACHE_TAG(cp, addr);
00767   md_addr_t set = CACHE_SET(cp, addr);
00768   struct cache_blk_t *blk;
00769 
00770   /* permissions are checked on cache misses */
00771 
00772   if (cp->hsize)
00773   {
00774     /* higly-associativity cache, access through the per-set hash tables */
00775     int hindex = CACHE_HASH(cp, tag);
00776     
00777     for (blk=cp->sets[set].hash[hindex];
00778          blk;
00779          blk=blk->hash_next)
00780     {   
00781       if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00782           return TRUE;
00783     }
00784   }
00785   else
00786   {
00787     /* low-associativity cache, linear search the way list */
00788     for (blk=cp->sets[set].way_head;
00789          blk;
00790          blk=blk->way_next)
00791     {
00792       if (blk->tag == tag && (blk->status & CACHE_BLK_VALID))
00793           return TRUE;
00794     }
00795   }
00796   
00797   /* cache block not found */
00798   return FALSE;
00799 }

void cache_reg_stats struct cache_t   cp,
struct stat_sdb_t   sdb
 

Definition at line 472 of file cache.c.

References cache_t::hits, cache_t::invalidations, cache_t::misses, cache_t::name, cache_t::replacements, stat_reg_counter, stat_reg_formula(), and cache_t::writebacks.

Referenced by sim_reg_stats().

00474 {
00475   char buf[512], buf1[512], *name;
00476 
00477   /* get a name for this cache */
00478   if (!cp->name || !cp->name[0])
00479     name = "<unknown>";
00480   else
00481     name = cp->name;
00482 
00483   sprintf(buf, "%s.accesses", name);
00484   sprintf(buf1, "%s.hits + %s.misses", name, name);
00485   stat_reg_formula(sdb, buf, "total number of accesses", buf1, "%12.0f");
00486   sprintf(buf, "%s.hits", name);
00487   stat_reg_counter(sdb, buf, "total number of hits", &cp->hits, 0, NULL);
00488   sprintf(buf, "%s.misses", name);
00489   stat_reg_counter(sdb, buf, "total number of misses", &cp->misses, 0, NULL);
00490   sprintf(buf, "%s.replacements", name);
00491   stat_reg_counter(sdb, buf, "total number of replacements",
00492                  &cp->replacements, 0, NULL);
00493   sprintf(buf, "%s.writebacks", name);
00494   stat_reg_counter(sdb, buf, "total number of writebacks",
00495                  &cp->writebacks, 0, NULL);
00496   sprintf(buf, "%s.invalidations", name);
00497   stat_reg_counter(sdb, buf, "total number of invalidations",
00498                  &cp->invalidations, 0, NULL);
00499   sprintf(buf, "%s.miss_rate", name);
00500   sprintf(buf1, "%s.misses / %s.accesses", name, name);
00501   stat_reg_formula(sdb, buf, "miss rate (i.e., misses/ref)", buf1, NULL);
00502   sprintf(buf, "%s.repl_rate", name);
00503   sprintf(buf1, "%s.replacements / %s.accesses", name, name);
00504   stat_reg_formula(sdb, buf, "replacement rate (i.e., repls/ref)", buf1, NULL);
00505   sprintf(buf, "%s.wb_rate", name);
00506   sprintf(buf1, "%s.writebacks / %s.accesses", name, name);
00507   stat_reg_formula(sdb, buf, "writeback rate (i.e., wrbks/ref)", buf1, NULL);
00508   sprintf(buf, "%s.inv_rate", name);
00509   sprintf(buf1, "%s.invalidations / %s.accesses", name, name);
00510   stat_reg_formula(sdb, buf, "invalidation rate (i.e., invs/ref)", buf1, NULL);
00511 }

void cache_stats struct cache_t   cp,
FILE *    stream
 

Definition at line 515 of file cache.c.

References cache_t::hits, cache_t::invalidations, cache_t::misses, cache_t::name, and cache_t::replacements.

00517 {
00518   double sum = (double)(cp->hits + cp->misses);
00519 
00520   fprintf(stream,
00521           "cache: %s: %.0f hits %.0f misses %.0f repls %.0f invalidations\n",
00522           cp->name, (double)cp->hits, (double)cp->misses,
00523           (double)cp->replacements, (double)cp->invalidations);
00524   fprintf(stream,
00525           "cache: %s: miss rate=%f  repl rate=%f  invalidation rate=%f\n",
00526           cp->name,
00527           (double)cp->misses/sum, (double)(double)cp->replacements/sum,
00528           (double)cp->invalidations/sum);
00529 }



UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214