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

cache.h

Go to the documentation of this file.
00001 /*
00002         Copyright (C) 1997 CFU Corporation
00003 
00004         File: cache.h
00005         Description: class Cache
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 
00022 #ifndef INCLUDED_CACHE_H
00023 #define INCLUDED_CACHE_H
00024 
00025 #include <stdio.h>
00026 #include <math.h>
00027 
00028 class Cache
00029 {
00030 public:
00031         Cache():_tag_array(NULL),_time_array(NULL),_valid_array(NULL),_dirty_array(NULL),_tag_array_in_stream_buffer(NULL),_valid_array_in_stream_buffer(NULL),_miss_or_hit_array(NULL) {}
00032 
00033         ~Cache() 
00034         {
00035                 delete[] _tag_array;
00036                 delete[] _time_array;
00037                 delete[] _miss_or_hit_array;
00038                 delete[] _valid_array;
00039                 delete[] _dirty_array;
00040 
00041                 delete[] _tag_array_in_stream_buffer;
00042                 delete[] _valid_array_in_stream_buffer;
00043         }
00044 
00045         Cache(int c, int b, int s,int p,int wp,int use):_c(c),_b(b),_s(s),_p(p),_wp(wp),_use_stream_buffer(use),_reads(0),_writes(0),_reads_in_miss(0),_writes_in_miss(0),_writebacks(0),_sb_reads_in_miss(0),_sb_writes_in_miss(0) 
00046         {
00047                 if(_c<_b || _c-_b<s)
00048                 {
00049                         fprintf(stderr,"ERROR (c b s)=(%d %d %d)\n",_c,_b,_s);
00050                         exit(0);
00051                 }
00052 
00053                 _bytes_in_cache=1<<c;
00054                 _sets_in_cache=1<<(c-b-s);
00055                 _blocks_in_set=1<<s;
00056                 _bytes_in_block=1<<b;
00057 
00058                 int num_of_tags=1<<(c-b);
00059                 _tag_array=new unsigned int[num_of_tags];
00060                 _time_array=new unsigned int[num_of_tags];
00061                 _miss_or_hit_array=new int[num_of_tags];
00062                 _valid_array=new char[num_of_tags];
00063                 _dirty_array=new char[num_of_tags];
00064 
00065                 for(int i=0;i<_sets_in_cache;i++)
00066                 {
00067                         for(int j=0;j<_blocks_in_set;j++)
00068                         {
00069                                 int index=i*_blocks_in_set+j;
00070                                 _valid_array[index]='i';
00071                                 _dirty_array[index]='c';
00072                                 _miss_or_hit_array[index]=0;
00073                         }
00074                 }
00075 
00076                 if(_use_stream_buffer==1)
00077                 {
00078                         _tag_array_in_stream_buffer=new unsigned int[_p];
00079                         _valid_array_in_stream_buffer=new char[_p];
00080                 }
00081         }
00082 
00083         void show_cache(FILE *f);
00084         void print_this_index(int this_index,int location);
00085 
00086         int simulate(char rw,unsigned int address,unsigned int global_time);
00087         void report(FILE *f);
00088 
00089         int bytes_in_block() {return _bytes_in_block;}
00090 
00091         /*
00092         int total_penalty()
00093         {
00094                 return 12*(_reads_in_miss+_writes_in_miss);
00095         }
00096         */
00097 
00098         int total_num_of_miss()
00099         {
00100                 return _reads_in_miss+_writes_in_miss;
00101         }
00102 
00103 private:
00104         int _c; // 2^c bytes
00105         int _b; // 2^b byte blocks
00106         int _s; // 2^s blocks per set. 
00107                 // Ex: s=0 direct-mapped cache
00108                 //     s=c-b fully associative cache
00109         int _p; // prefetching sequentail blocks
00110         int _wp;        // wp=0 write back policy
00111                         // wp=1 write-through-no-allocate
00112         int _use_stream_buffer; // 0 use
00113                                 // 1 no use
00114 
00115         int _bytes_in_cache;    // number of bytes in the cache
00116         int _sets_in_cache;     // number of sets in the cache
00117         int _blocks_in_set;     // number of blocks in one set
00118         int _bytes_in_block;    // number_of_bytes in one block
00119 
00120         unsigned int *_tag_array;       // store tags in cache
00121         unsigned int *_time_array;              // store time in cache
00122         int *_miss_or_hit_array;                // store hit or miss last time
00123         char *_valid_array;     // store valid bits v=>valid i=>invalid 
00124         char *_dirty_array;     // store direty bits, d=>dirty c=>clean
00125 
00126         unsigned int *_tag_array_in_stream_buffer;      // store tags in stream buffer
00127         char *_valid_array_in_stream_buffer;    // store valid bits in stream buffer
00128 
00129         int _reads;     // num of reads
00130         int _writes;    // num of writes
00131         int _reads_in_miss;     // num of read miss
00132         int _writes_in_miss;    // num of write miss
00133         int _writebacks;        // num of write backs from L1
00134 
00135         int _sb_reads_in_miss;
00136         int _sb_writes_in_miss;
00137 };
00138 
00139 //
00140 // To support compress encoding in the memory
00141 // Read: Instruction fetch mechanisms for VLIW architectures with compressed 
00142 //       encoding
00143 //
00144 class Banked_Cache
00145 {
00146     private:
00147     //HZ: The statistic of the banked cache.
00148     // Due to the characteristics of the banked cache, the total miss is not
00149     // equal to the misses of the two subbanks.
00150     // The reason: if a MOP requires two banks access (e.g., its start_address
00151     // is in bank 0 and end_address is in bank1) and both banks report miss,    
00152     // there would be two misses if we sum them up. However, as the miss can be
00153     // processed with a fetch of 2 consecutive blocks, this is only one miss
00154     // penalty actually.
00155     //So we keep account of the cache misses at this banked cache level
00156     int t_cache_access;
00157     int t_cache_misses;
00158     int t_cache_access_both_banks;
00159     
00160 public:
00161         Banked_Cache():_bank0(NULL),_bank1(NULL),_block_size(0)
00162         {
00163                 //_bank0=new Cache(14,5,0,0,0,0);       // 16K bytes, 32-byte line direct mapped
00164                 //_bank1=new Cache(14,5,0,0,0,0);       // 16K bytes, 32-byte line direct mapped
00165         }
00166 
00167         Banked_Cache(int c,int b,int s):_c(c),_b(b),_s(s)
00168         {
00169                 int half_size=_c-1;
00170                 _block_size=1<<_b;
00171 
00172                 //HZ: why??
00173                 //It seems more associativity is a GOOD thing for miss rate.
00174                 //assert(_s==0);        // ONLY WORK FOR DIRECT MAP NOW
00175 
00176                 _bank0=new Cache(half_size,_b,_s,0,0,0);        
00177                 _bank1=new Cache(half_size,_b,_s,0,0,0);
00178                 
00179                 //HZ:
00180                 t_cache_access = 0;
00181                 t_cache_misses = 0;
00182                 t_cache_access_both_banks = 0;
00183         }
00184 
00185         ~Banked_Cache() 
00186         {
00187                 delete _bank0;
00188                 delete _bank1;
00189         }
00190 
00191         void simulate(char rw,unsigned int start_address,unsigned int num_of_op,unsigned int global_time)
00192         {
00193             //HZ:
00194             t_cache_access++;
00195                 //
00196                 // Step 1. calculate the end address of the last op
00197                 //
00198                 unsigned int end_address=start_address+(num_of_op-1)*4;
00199                 unsigned int end_upper_portion=end_address>>_b;
00200 
00201                 //
00202                 // Step 2. Determine which banks to go
00203                 //
00204                 unsigned int start_upper_portion=start_address>>_b;
00205                 unsigned int bank_id=start_upper_portion%2;
00206 
00207                 //
00208                 // Step 3. Check if we need to access two banks
00209                 //
00210                 bool need_only_one_bank=false;
00211                 if(start_upper_portion==end_upper_portion)
00212                 {
00213                         need_only_one_bank=true;
00214                 }
00215 
00216                 //
00217                 // In order to reuse Cache class
00218                 // Hack address for bank0 and bank1
00219                 // => shift right 1 bit
00220                 //
00221                 unsigned int address_bank0=0;
00222                 unsigned int address_bank1=0;
00223 
00224                 if(bank_id==0)  // Fetch start from bank 0
00225                 {
00226                         address_bank0=start_address>>1;
00227 
00228                         if(need_only_one_bank==true)
00229                         {
00230                             //HZ:
00231                             int hit_miss;
00232                             hit_miss = _bank0->simulate(rw,address_bank0,global_time);
00233                             assert(hit_miss <= 1);
00234                             t_cache_misses += (1 - hit_miss);
00235                                 //_bank0->simulate(rw,address_bank0,global_time);
00236                         }
00237                         else    // access two banks
00238                         {
00239                             //HZ:
00240                             t_cache_access_both_banks++;
00241                                 // bank1 use the same address
00242                                 address_bank1=end_address>>1;
00243 
00244                                 //HZ:
00245                                 //_bank0->simulate(rw,address_bank0,global_time);
00246                                 //_bank1->simulate(rw,address_bank1,global_time);
00247                                 int hit_miss0, hit_miss1;
00248                                 hit_miss0 = _bank0->simulate(rw,address_bank0,global_time);
00249                                 assert(hit_miss0 <= 1);
00250                                 hit_miss1 = _bank1->simulate(rw,address_bank1,global_time);
00251                                 assert(hit_miss1 <= 1);
00252                                 t_cache_misses += (1 - (hit_miss1 & hit_miss0)); 
00253                         }
00254 
00255                 }
00256                 else    // Fetch start from bank 1
00257                 {
00258                         address_bank1=start_address>>1;
00259 
00260                         if(need_only_one_bank==true)
00261                         {
00262                             //HZ:
00263                             int hit_miss;
00264                             hit_miss = _bank1->simulate(rw,address_bank1,global_time);
00265                             assert(hit_miss <= 1);
00266                             t_cache_misses += (1 - hit_miss);
00267                                 //_bank1->simulate(rw,address_bank1,global_time);
00268                         }
00269                         else    // access two banks
00270                         {
00271                             //HZ:
00272                             t_cache_access_both_banks++;
00273                                 // bank0 use the different address
00274                                 address_bank0=end_address>>1;
00275 
00276                                 //HZ:
00277                                 //_bank1->simulate(rw,address_bank1,global_time);
00278                                 //_bank0->simulate(rw,address_bank0,global_time);
00279                                 int hit_miss0, hit_miss1;
00280                                 hit_miss1 = _bank1->simulate(rw,address_bank1,global_time);
00281                                 assert(hit_miss1 <= 1);
00282                                 hit_miss0 = _bank0->simulate(rw,address_bank0,global_time);
00283                                 assert(hit_miss0 <= 1);
00284                                 t_cache_misses += (1 - (hit_miss1 & hit_miss0));                                
00285                         }
00286                 }
00287 
00288                 //fprintf(stderr,"Start Address is %u\n",start_address);
00289                 //fprintf(stderr,"End Address is %u\n",end_address);
00290                 //fprintf(stderr,"Fetch one bank=%d\nFrom bank %d: bank0 %u bank1 %u\n",need_only_one_bank,bank_id,address_bank0,address_bank1);
00291 
00292         }
00293 
00294         void show_cache(FILE *f);
00295         void report(FILE *f);
00296         //int total_penalty();
00297 
00298         int total_num_of_miss();
00299 
00300 private:
00301         Cache *_bank0;
00302         Cache *_bank1;
00303 
00304         int _c; // 2^c bytes
00305         int _b; // 2^b byte blocks
00306         int _s; // 2^s blocks per set. 
00307                 // Ex: s=0 direct-mapped cache
00308                 //     s=c-b fully associative cache
00309         unsigned int _block_size;       // size of block = 2^_b
00310 };
00311 
00312 #endif // INCLUDED_CACHE_H

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