Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

cache.cpp

Go to the documentation of this file.
00001 /*
00002         Copyright (C) 1997 CFU Corporation
00003 
00004         File: cache.cpp
00005         Description: class Cache implementation
00006         Author: Chao-yinig Fu
00007         Date: Apr. 6 2000
00008 
00009         ^..^
00010         (00)
00011 
00012          $__$
00013         <~00~>
00014          (oo)
00015           ||
00016 
00017         ```````
00018         C ^|^ D
00019          \ O /
00020 */
00021 #include <stdio.h>
00022 #include <assert.h>
00023 
00024 #include "cache.h"
00025 
00026 //
00027 // Return 1 if hit
00028 // Return 0 if miss
00029 //
00030 int Cache::simulate(char rw,unsigned int address,unsigned int global_time)
00031 {
00032         unsigned int this_tag=address>>(_c-_s);
00033         unsigned int this_index=(address>>_b)&((1<<(_c-_b-_s))-1);
00034 
00035         unsigned int location=this_index*_blocks_in_set;
00036         int miss_or_hit;
00037         unsigned int old_time;  // record the old time of the hit block
00038         int miss_or_hit_last_time;
00039 
00040         /*
00041         if(0)
00042         {
00043         fprintf(stderr,"\n*** %c %8x ***\n\n",rw,address);
00044         fprintf(stderr,"===L1 CACHE===\n");
00045         fprintf(stderr,"index = %x, tag = %x\n",this_index,this_tag);
00046         }
00047         */
00048 
00049 /*--------------------------------------------------------------------------*/
00050         if(rw=='r')     // read
00051 /*--------------------------------------------------------------------------*/
00052         {
00053                 _reads++;
00054 
00055                 miss_or_hit=0;
00056 
00057                 int index;
00058                 for(int i=0;i<_blocks_in_set;i++)
00059                 {
00060                         index=location+i;
00061                         if(_valid_array[index]=='v' && _tag_array[index]==this_tag)
00062                         {
00063                                 miss_or_hit=1;
00064                                 break;
00065                         }
00066                 }
00067 
00068 
00069 /*--------------------------------------------------------------------------*/
00070                 if(miss_or_hit==1)              /* read hit */
00071 /*--------------------------------------------------------------------------*/
00072                 {
00073                         /*
00074                         if(0)
00075                         {
00076                         fprintf(stderr,"HIT\n");
00077                         fprintf(stderr,"(BEFORE)");
00078                         print_this_index(this_index,location);
00079                         }
00080                         */
00081 
00083                         old_time=_time_array[index];
00084                         miss_or_hit_last_time=_miss_or_hit_array[index];
00085                         _miss_or_hit_array[index]=1;
00087 
00088                         _time_array[index]=global_time;
00089                 }
00090 /*--------------------------------------------------------------------------*/
00091                 else                          /* read miss */
00092 /*--------------------------------------------------------------------------*/
00093                 {
00094                         /*
00095                         if(0)
00096                         {
00097                         fprintf(stderr,"MISS\n");
00098                         fprintf(stderr,"(BEFORE)");
00099                         print_this_index(this_index,location);
00100                         }
00101                         */
00102 
00103                         _reads_in_miss++;
00104 
00105                         /* find a empty block to put */
00106                         int i;
00107                         int target;     // records which block it reads
00108                         for(i=0;i<_blocks_in_set;i++)
00109                         {
00110                                 int index=location+i;
00111                                 if(_valid_array[index]=='i')
00112                                 {
00114                                         _miss_or_hit_array[index]=0;
00116 
00117                                         _valid_array[index]='v';
00118                                         _dirty_array[index]='c';
00119                                         _tag_array[index]=this_tag;
00120                                         _time_array[index]=global_time;
00121                                         target=i;
00122                                         break;
00123                                 }
00124                         }
00125                         /* set is full, need LRU replacement */
00126                         if(i==_blocks_in_set)
00127                         {
00128                                 target=0;
00129                                 for(int j=1;j<_blocks_in_set;j++)
00130                                 {
00131                                         if(_time_array[location+target]>_time_array[location+j])
00132                                         {
00133                                                 target=j;
00134                                         }
00135                                 }
00136                                 
00137                                 /* dirty block should write back */
00138                                 int index=location+target;
00139                                 if(_dirty_array[index]=='d')
00140                                 {
00141                                         _writebacks++;
00142                                 }
00143 
00145                                 _miss_or_hit_array[index]=0;
00147 
00148                                 _valid_array[index]='v';
00149                                 _dirty_array[index]='c';
00150                                 _tag_array[index]=this_tag;
00151                                 _time_array[index]=global_time;
00152                         }
00153                 }
00154 
00155         }
00156 /*--------------------------------------------------------------------------*/
00157         else if(rw=='w')        // write
00158 /*--------------------------------------------------------------------------*/
00159         {
00160                 _writes++;
00161 
00162                 miss_or_hit=0;
00163 
00164                 int index;
00165                 for(int i=0;i<_blocks_in_set;i++)
00166                 {
00167                         index=location+i;
00168                         if(_valid_array[index]=='v' && _tag_array[index]==this_tag)
00169                         {
00170                                 miss_or_hit=1;
00171                                 break;
00172                         }
00173                 }
00174 
00175 /*--------------------------------------------------------------------------*/
00176                 if(miss_or_hit==1)      /* write hit */
00177 /*--------------------------------------------------------------------------*/
00178                 {
00179                         /*
00180                         if(0)
00181                         {
00182                         fprintf(stderr,"HIT\n");
00183                         fprintf(stderr,"(BEFORE)");
00184                         print_this_index(this_index,location);
00185                         }
00186                         */
00187 
00188                         if(_wp==0)      // write back (write allocate)
00189                         {
00190                                 _dirty_array[index]='d';
00191                         }
00192                         else if(_wp==1) // write through (no allocate)
00193                         {
00194                                 _dirty_array[index]='c';
00195                                 _writebacks++;
00196                         }
00197 
00198                         _tag_array[index]=this_tag;
00199 
00201                         old_time=_time_array[index];
00202                         miss_or_hit_last_time=_miss_or_hit_array[index];
00203                         _miss_or_hit_array[index]=1;
00205 
00206                         _time_array[index]=global_time;
00207                 }
00208 /*--------------------------------------------------------------------------*/
00209                 else                    /* write miss*/
00210 /*--------------------------------------------------------------------------*/
00211                 {
00212                         /*
00213                         if(0)
00214                         {
00215                         fprintf(stderr,"MISS\n");
00216                         fprintf(stderr,"(BEFORE)");
00217                         print_this_index(this_index,location);
00218                         }
00219                         */
00220 
00221                         if(_wp==1)      /* no allocate (write through)*/
00222                         {
00223                                 _writebacks++;
00224                         }
00225                         else if(_wp==0) /* write allocate (write back)*/
00226                         {
00227                                 _writes_in_miss++;
00228 
00229                                 /* find a block to write */
00230                                 int i;
00231                                 int target;
00232                                 for(i=0;i<_blocks_in_set;i++)
00233                                 {
00234                                         int index=location+i;
00235                                         if(_valid_array[index]=='i')
00236                                         {
00238                                                 _miss_or_hit_array[index]=0;
00240 
00241                                                 _valid_array[index]='v';
00242                                                 _tag_array[index]=this_tag;
00243                                                 _dirty_array[index]='d';
00244                                                 _time_array[index]=global_time;
00245                                                 target=i;
00246                                                 break;
00247                                         }
00248                                 }
00249 
00250                                 if(i==_blocks_in_set)   // need LRU Replacement
00251                                 {
00252                                         target=0;
00253                                         for(int j=1;j<_blocks_in_set;j++)
00254                                         {
00255                                                 if(_time_array[location+target]>_time_array[location+j])
00256                                                 {
00257                                                         target=j;
00258                                                 }
00259                                         }
00260 
00261                                         /* dirty block should write back */
00262                                         int index=location+target;
00263                                         if(_dirty_array[index]=='d')
00264                                         {
00265                                                 _writebacks++;
00266                                         }
00267 
00269                                         _miss_or_hit_array[index]=0;
00271                                         
00272                                         _valid_array[index]='v';
00273                                         _dirty_array[index]='d';
00274                                         _tag_array[index]=this_tag;
00275                                         _time_array[index]=global_time;
00276                                 }
00277                         }
00278                 }
00279 
00280         }
00281 
00282         /*
00283         if(0)
00284         {
00285         fprintf(stderr,"(AFTER )");
00286         print_this_index(this_index,location);
00287         }
00288         */
00289 
00290         //getchar();
00291 
00292         // If hit and the current global_time is the same as old_time
00293         // it means, we access the same block at the same time
00294         // we should consider hit_or_miss from its previous status
00295         if(miss_or_hit==1 && old_time==global_time)
00296         {
00297                 return miss_or_hit_last_time;
00298         }
00299         else
00300         {
00301                 return miss_or_hit;
00302         }
00303 }
00304 
00305 void Cache::print_this_index(int this_index,int location)
00306 {
00307         fprintf(stderr," set %5d:",this_index);
00308 
00309         for(int i=0;i<_blocks_in_set;i++)
00310         {
00311                 int index=location+i;
00312                 if(_valid_array[index]=='v')
00313                 {
00314                         fprintf(stderr," %8x",_tag_array[index]);
00315                         if(_dirty_array[index]=='d')
00316                         {
00317                                 fprintf(stderr," D");
00318                         }
00319                         else
00320                         {
00321                                 fprintf(stderr,"  ");
00322                         }
00323 
00324                         fprintf(stderr," (%d)",i);
00325                 }
00326         }
00327 
00328         fprintf(stderr,"\n");
00329 }
00330 
00331 void Cache::report(FILE *f)
00332 {
00333         fprintf(f,"\treads:\t\t%d\n",_reads);
00334         fprintf(f,"\tread misses:\t%d\n",_reads_in_miss);
00335         fprintf(f,"\twrites:\t\t%d\n",_writes);
00336         fprintf(f,"\twrite misses:\t%d\n",_writes_in_miss);
00337         fprintf(f,"\twritebacks from L1:\t%d\n",_writebacks);
00338         double miss=(double)(_reads_in_miss+_writes_in_miss)/(_reads+_writes);
00339         fprintf(f,"\tL1 miss rate:\t%.4f\n",miss);
00340 }
00341 
00342 void Cache::show_cache(FILE *f)
00343 {
00344         fprintf(f,"\tSIZE:\t\t\t%d bytes (%.1f KB)\n",_bytes_in_cache,(double)_bytes_in_cache/1024);
00345         fprintf(f,"\tASSOC:\t\t\t%d\n",_blocks_in_set);
00346         fprintf(f,"\tBLOCKSIZE:\t\t%d bytes\n",_bytes_in_block);
00347         if(_wp==0)
00348         {
00349                 fprintf(f,"\tWrite Policy:\t\tWBWA\n");
00350         }
00351         else if(_wp==1)
00352         {
00353                 fprintf(f,"\tWrite Policy:\t\tWTNA\n");
00354         }
00355         /*
00356         fprintf(f,"\tPrefetch Seq:\t\t%d\n",_p);
00357         fprintf(f,"\tUse Stream Buffer:\t");
00358         if(_use_stream_buffer==0)
00359         {
00360                 fprintf(stderr,"No\n");
00361         }
00362         else if(_use_stream_buffer==1)
00363         {
00364                 fprintf(stderr,"Yes\n");
00365         }
00366         */
00367         /*
00368         fprintf(f,"======= L2 CACHE =======\n");
00369         fprintf(f,"Off\n");
00370         */
00371 }
00372 
00373 void Banked_Cache::show_cache(FILE *f)
00374 {
00375         fprintf(f,"bank0\n");
00376         _bank0->show_cache(f);
00377         fprintf(f,"bank1\n");
00378         _bank1->show_cache(f);
00379 }
00380 
00381 void Banked_Cache::report(FILE *f)
00382 {
00383         fprintf(f,"bank0\n");
00384         _bank0->report(f);
00385         fprintf(f,"bank1\n");
00386         _bank1->report(f);
00387         
00388         //HZ:
00389         fprintf(f, "Overall: \n");
00390         fprintf(f, "cache accesses: %d, cache misses: %d \n", t_cache_access,
00391                 t_cache_misses);
00392         fprintf(f, "access both banks: %d \n", t_cache_access_both_banks);
00393         fprintf(f, "miss rate: %f, miss penalties: %d\n", t_cache_misses * 1.0 /
00394                 t_cache_access, t_cache_misses * 12);
00395 }
00396 
00397 /*
00398 int Banked_Cache::total_penalty()
00399 {
00400         int bank0_penalty=_bank0->total_penalty();
00401         int bank1_penalty=_bank1->total_penalty();
00402 
00403         return bank0_penalty+bank1_penalty;
00404 }
00405 */
00406 
00407 int Banked_Cache::total_num_of_miss()
00408 {
00409         int bank0_miss=_bank0->total_num_of_miss();
00410         int bank1_miss=_bank1->total_num_of_miss();
00411 
00412         return bank0_miss+bank1_miss;
00413 }

Generated on Mon Jul 21 20:24:03 2003 for TINKER LEGO DOC by doxygen 1.3.2