/************************************************************************ ** ** Dinero III Cache Simulator ** $Header: /var/home/markhill/DistributeDineroIII/RCS/output.c,v 3.3 89/05/04 09:57:39 markhill Exp $ ** Similar to Version 3.1, Released 8/7/85 ** ** Mark D. Hill ** Computer Sciences Dept. ** Univ. of Wisconsin ** Madison, WI 53706 ** markhill@cs.wisc.edu ** ** Developed DineroIII While Affiliated With: ** ** Computer Science Division ** University of California ** Berkeley, California 94720 ** ** Source File: output.c ** ************************************************************************/ /* ** Copyright 1985, 1989 Mark D. Hill ** ** Permission to use, copy, modify, and distribute this ** software and its documentation for any purpose and without ** fee is hereby granted, provided that the above copyright ** notice appear in all copies. Mark D. Hill makes no ** representations about the suitability of this software ** for any purpose. It is provided "as is" without expressed ** or implied warranty. */ #include "global.h" /* ** Used so that "numerator / NONZERO(denomenator)" will ** never cause a divide-by-zero exception. */ #define NONZERO(i) ((i==0) ? 1.0 : (float)i) outputmetric(cachep,policyp,ctrlp,m) CACHETYPE *cachep; /* < */ POLICYTYPE *policyp; /* < */ CTRLTYPE *ctrlp; /* < */ METRICTYPE *m; /* < Too lazy to write "metricp" */ /* ** affects: none ** returns: OK */ { int demand_fetch_data, demand_fetch_alltype; int prefetch_fetch_data, prefetch_fetch_alltype; int demand_data, demand_alltype; int prefetch_data, prefetch_alltype; float floatnum; /* Used in bus traffic calculations even if no prefetching. */ prefetch_fetch_alltype = 0; /* ** Print Header */ printf("\n"); printf(" Metrics Access Type:\n"); printf( " (totals,fraction) Total Instrn Data Read Write Misc\n"); printf( " ----------------- ------ ------ ------ ------ ------ ------\n"); /* ** Print Fetch Numbers */ demand_fetch_data = m->fetch[XMISC] + m->fetch[XREAD] + m->fetch[XWRITE]; demand_fetch_alltype = demand_fetch_data + m->fetch[XINSTRN]; printf( " Demand Fetches %6d %6d %6d %6d %6d %6d\n", demand_fetch_alltype, m->fetch[XINSTRN], demand_fetch_data, m->fetch[XREAD], m->fetch[XWRITE], m->fetch[XMISC] ); floatnum = NONZERO(demand_fetch_alltype); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", demand_fetch_alltype / floatnum, m->fetch[XINSTRN] / floatnum, demand_fetch_data / floatnum, m->fetch[XREAD] / floatnum, m->fetch[XWRITE] / floatnum, m->fetch[XMISC] / floatnum ); /* ** Prefetching? */ if (policyp->fetch!=DEMAND) { prefetch_fetch_data = m->fetch[PREFETCH+XMISC] + m->fetch[PREFETCH+XREAD] + m->fetch[PREFETCH+XWRITE]; prefetch_fetch_alltype = prefetch_fetch_data + m->fetch[PREFETCH+XINSTRN]; printf( " Prefetch Fetches %6d %6d %6d %6d %6d %6d\n", prefetch_fetch_alltype, m->fetch[PREFETCH+XINSTRN], prefetch_fetch_data, m->fetch[PREFETCH+XREAD], m->fetch[PREFETCH+XWRITE], m->fetch[PREFETCH+XMISC] ); floatnum = NONZERO(prefetch_fetch_alltype); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", prefetch_fetch_alltype / floatnum, m->fetch[PREFETCH+XINSTRN] / floatnum, prefetch_fetch_data / floatnum, m->fetch[PREFETCH+XREAD] / floatnum, m->fetch[PREFETCH+XWRITE] / floatnum, m->fetch[PREFETCH+XMISC] / floatnum ); printf( " Total Fetches %6d %6d %6d %6d %6d %6d\n", demand_fetch_alltype + prefetch_fetch_alltype, m->fetch[XINSTRN] + m->fetch[PREFETCH+XINSTRN], demand_fetch_data + prefetch_fetch_data, m->fetch[XREAD] + m->fetch[PREFETCH+XREAD], m->fetch[XWRITE] + m->fetch[PREFETCH+XWRITE], m->fetch[XMISC] + m->fetch[PREFETCH+XMISC] ); floatnum = NONZERO(demand_fetch_alltype + prefetch_fetch_alltype); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", (demand_fetch_alltype + prefetch_fetch_alltype) / floatnum, (m->fetch[XINSTRN] + m->fetch[PREFETCH+XINSTRN]) / floatnum, (demand_fetch_data + prefetch_fetch_data) / floatnum, (m->fetch[XREAD] + m->fetch[PREFETCH+XREAD]) / floatnum, (m->fetch[XWRITE] + m->fetch[PREFETCH+XWRITE]) / floatnum, (m->fetch[XMISC] + m->fetch[PREFETCH+XMISC]) / floatnum ); } /* End of prefetching. */ printf("\n"); /* ** End of Fetch Numbers */ /* ** Print Miss Numbers */ demand_data = m->miss[XMISC] + m->miss[XREAD] + m->miss[XWRITE]; demand_alltype = demand_data + m->miss[XINSTRN]; printf( " Demand Misses %6d %6d %6d %6d %6d %6d\n", demand_alltype, m->miss[XINSTRN], demand_data, m->miss[XREAD], m->miss[XWRITE], m->miss[XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", demand_alltype / NONZERO(demand_fetch_alltype), m->miss[XINSTRN] / NONZERO(m->fetch[XINSTRN]), demand_data / NONZERO(demand_fetch_data), m->miss[XREAD] / NONZERO(m->fetch[XREAD]), m->miss[XWRITE] / NONZERO(m->fetch[XWRITE]), m->miss[XMISC] / NONZERO(m->fetch[XMISC]) ); /* ** Prefetching? */ if (policyp->fetch!=DEMAND) { prefetch_data = m->miss[PREFETCH+XMISC] + m->miss[PREFETCH+XREAD] + m->miss[PREFETCH+XWRITE]; prefetch_alltype = prefetch_data + m->miss[PREFETCH+XINSTRN]; printf( " Prefetch Misses %6d %6d %6d %6d %6d %6d\n", prefetch_alltype, m->miss[PREFETCH+XINSTRN], prefetch_data, m->miss[PREFETCH+XREAD], m->miss[PREFETCH+XWRITE], m->miss[PREFETCH+XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", prefetch_alltype / NONZERO(prefetch_fetch_alltype), m->miss[PREFETCH+XINSTRN] / NONZERO(m->fetch[PREFETCH+XINSTRN]), prefetch_data / NONZERO(prefetch_fetch_data), m->miss[PREFETCH+XREAD] / NONZERO(m->fetch[PREFETCH+XREAD]), m->miss[PREFETCH+XWRITE] / NONZERO(m->fetch[PREFETCH+XWRITE]), m->miss[PREFETCH+XMISC] / NONZERO(m->fetch[PREFETCH+XMISC]) ); printf( " Total Misses %6d %6d %6d %6d %6d %6d\n", demand_alltype + prefetch_alltype, m->miss[XINSTRN] + m->miss[PREFETCH+XINSTRN], demand_data + prefetch_data, m->miss[XREAD] + m->miss[PREFETCH+XREAD], m->miss[XWRITE] + m->miss[PREFETCH+XWRITE], m->miss[XMISC] + m->miss[PREFETCH+XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", (demand_alltype + prefetch_alltype) / NONZERO(demand_fetch_alltype + prefetch_fetch_alltype), (m->miss[XINSTRN] + m->miss[PREFETCH+XINSTRN]) / NONZERO(m->fetch[XINSTRN] + m->fetch[PREFETCH+XINSTRN]), (demand_data + prefetch_data) / NONZERO(demand_fetch_data + prefetch_fetch_data), (m->miss[XREAD] + m->miss[PREFETCH+XREAD]) / NONZERO(m->fetch[XREAD] + m->fetch[PREFETCH+XREAD]), (m->miss[XWRITE] + m->miss[PREFETCH+XWRITE]) / NONZERO(m->fetch[XWRITE] + m->fetch[PREFETCH+XWRITE]), (m->miss[XMISC] + m->miss[PREFETCH+XMISC]) / NONZERO(m->fetch[XMISC] + m->fetch[PREFETCH+XMISC]) ); } /* End of prefetching. */ printf("\n"); /* ** End of Misses Numbers */ /* ** Print Block Miss Numbers */ if (cachep->subblocksize!=0) { demand_data = m->blockmiss[XMISC] + m->blockmiss[XREAD] + m->blockmiss[XWRITE]; demand_alltype = demand_data + m->blockmiss[XINSTRN]; printf( " Demand Block Misses %6d %6d %6d %6d %6d %6d\n", demand_alltype, m->blockmiss[XINSTRN], demand_data, m->blockmiss[XREAD], m->blockmiss[XWRITE], m->blockmiss[XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", demand_alltype / NONZERO(demand_fetch_alltype), m->blockmiss[XINSTRN] / NONZERO(m->fetch[XINSTRN]), demand_data / NONZERO(demand_fetch_data), m->blockmiss[XREAD] / NONZERO(m->fetch[XREAD]), m->blockmiss[XWRITE] / NONZERO(m->fetch[XWRITE]), m->blockmiss[XMISC] / NONZERO(m->fetch[XMISC]) ); /* ** Prefetching? */ if (policyp->fetch!=DEMAND) { prefetch_data = m->blockmiss[PREFETCH+XMISC] + m->blockmiss[PREFETCH+XREAD] + m->blockmiss[PREFETCH+XWRITE]; prefetch_alltype = prefetch_data + m->blockmiss[PREFETCH+XINSTRN]; printf( " Prefetch Block Misses %6d %6d %6d %6d %6d %6d\n", prefetch_alltype, m->blockmiss[PREFETCH+XINSTRN], prefetch_data, m->blockmiss[PREFETCH+XREAD], m->blockmiss[PREFETCH+XWRITE], m->blockmiss[PREFETCH+XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", prefetch_alltype / NONZERO(prefetch_fetch_alltype), m->blockmiss[PREFETCH+XINSTRN] / NONZERO(m->fetch[PREFETCH+XINSTRN]), prefetch_data / NONZERO(prefetch_fetch_data), m->blockmiss[PREFETCH+XREAD] / NONZERO(m->fetch[PREFETCH+XREAD]), m->blockmiss[PREFETCH+XWRITE] / NONZERO(m->fetch[PREFETCH+XWRITE]), m->blockmiss[PREFETCH+XMISC] / NONZERO(m->fetch[PREFETCH+XMISC]) ); printf( " Total Block Misses %6d %6d %6d %6d %6d %6d\n", demand_alltype + prefetch_alltype, m->blockmiss[XINSTRN] + m->blockmiss[PREFETCH+XINSTRN], demand_data + prefetch_data, m->blockmiss[XREAD] + m->blockmiss[PREFETCH+XREAD], m->blockmiss[XWRITE] + m->blockmiss[PREFETCH+XWRITE], m->blockmiss[XMISC] + m->blockmiss[PREFETCH+XMISC] ); printf( " %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", (demand_alltype + prefetch_alltype) / NONZERO(demand_fetch_alltype + prefetch_fetch_alltype), (m->blockmiss[XINSTRN] + m->blockmiss[PREFETCH+XINSTRN]) / NONZERO(m->fetch[XINSTRN] + m->fetch[PREFETCH+XINSTRN]), (demand_data + prefetch_data) / NONZERO(demand_fetch_data + prefetch_fetch_data), (m->blockmiss[XREAD] + m->blockmiss[PREFETCH+XREAD]) / NONZERO(m->fetch[XREAD] + m->fetch[PREFETCH+XREAD]), (m->blockmiss[XWRITE] + m->blockmiss[PREFETCH+XWRITE]) / NONZERO(m->fetch[XWRITE] + m->fetch[PREFETCH+XWRITE]), (m->blockmiss[XMISC] + m->blockmiss[PREFETCH+XMISC]) / NONZERO(m->fetch[XMISC] + m->fetch[PREFETCH+XMISC]) ); } /* End of prefetching. */ printf("\n"); } /* End of block miss. */ /* ** End of Block Misses Numbers */ /* ** Print Bus Traffic Numbers */ printf( " Words From Memory %6ld\n", m->bus_traffic_in / cachep->wordsize ); printf( " ( / Demand Fetches) %6.4f\n", (m->bus_traffic_in / cachep->wordsize) / NONZERO(demand_fetch_alltype) ); printf( " Words Copied-Back %6ld\n", m->bus_traffic_out / cachep->wordsize ); printf( " ( / Demand Writes) %6.4f\n", (m->bus_traffic_out / cachep->wordsize) / NONZERO(m->fetch[XWRITE]) ); printf( " Total Traffic (words) %6ld\n", (m->bus_traffic_in + m->bus_traffic_out) / cachep->wordsize ); printf( " ( / Demand Fetches) %6.4f\n", ((m->bus_traffic_in + m->bus_traffic_out) / cachep->wordsize) / NONZERO(demand_fetch_alltype) ); printf( " Total Bus Transactions (Bursts) %6ld\n", m->bus_transactions_initiated ); printf( " Total Bus Usage (Cycles) %6ld\n", m->bus_usage ); printf("\n"); /* ** End of Bus Traffic */ } /* ***************************************************************** */ dumpaddr(number,dap) /* Dumps decoded address */ long number; /* < */ register DECODEDADDRTYPE *dap; /* < */ /* ** affects: none ** returns: OK */ { if (sizeof(long)>sizeof(int)) printf("\n### %ld ### Access=0x%x, Addr=0x%lx, TSB=0x%lx@%x@%x, subbit=0x%x.\n", number,dap->accesstype,dap->address, dap->tag,dap->set,dap->block,dap->validbit); /* @@ changed second and third %x in print string into %lx */ else printf("\n### %d ### Access=0x%x, Addr=0x%lx, TSB=0x%lx@%x@%x, subbit=0x%x.\n", number,dap->accesstype,dap->address, dap->tag,dap->set,dap->block,dap->validbit); /* @@ changed second and third %x in print string into %lx */ } /* ***************************************************************** */ dumpstate(cachep,policyp) /* Dumps info on stacks & free list */ register CACHETYPE *cachep; /* < */ POLICYTYPE *policyp; /* < */ /* ** affects: none ** returns: OK */ { extern STACKNODETYPE *stack; /* global ptr to top of stacks */ extern int bufferindex; /* global index to buffer */ extern STACKNODETYPE freelist; /* List head for free list */ extern int numnodes; /* Count on storage allocated */ register int i; register int sum; register STACKNODETYPE *ptr; int num_of_sets; sum = 0; num_of_sets = cachep->numIsets + cachep->numUorDsets; printf("\nStack Number Size Cum Size\n"); printf( "----------- ---- --------\n"); for (i=0; i0) { printf("%10x %6d %10d\t",i,stack[i].tag,(sum += stack[i].tag)); for (ptr=stack[i].next; ptr!=NULL; ptr=ptr->next) { printf("(%lx,%lx",ptr->tag,ptr->blockaddr); /* @@ changed from %x into %lx */ if ((cachep->subblocksize>0)||(ptr->valid!=VALID)) { printf(",V%x",ptr->valid); } if ((policyp->fetch==TAGGEDPREFETCH) || (ptr->reference!=NOTREFERENCED)){ printf(",R%x",ptr->reference); } if ((policyp->write==COPYBACK)||(ptr->dirty!=NOTDIRTY)) { printf(",D%x",ptr->dirty); } printf(")"); } printf("\n"); } printf("%d elements allocated, %d on priority stacks, %d on freelist,\n", numnodes, sum, freelist.tag); printf("%d unused in buffer%s\n", (BUFFERSIZE-bufferindex), ((numnodes - sum - freelist.tag - BUFFERSIZE + bufferindex)==0 ? "." : "(*** error: stacks are inconsistent).")); } /* ***************************************************************** */ dumpmetric(metricp,cachep) /* Dumps cache performance measures */ METRICTYPE *metricp; /* < */ CACHETYPE *cachep; /* < */ /* ** affects: none ** returns: OK */ { printf("\n Procedure dumpmetric unimplemented.\n\n"); } /* ***************************************************************** */