Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
config_cache.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 // This may look like C code, but it is really -*- C++ -*-
00037 //
00038 // ====================================================================
00039 // ====================================================================
00040 //
00041 // Revision history:
00042 //  14-Nov-96 - Original Version, copied from cache_parameters.cxx.
00043 //
00044 // Description:
00045 //
00046 // This is the description of the memory hierarcy.  It is only used
00047 // to determine how to SNL transform and for prefetching.  There's no
00048 // need to model memory hierarchy levels that are to be ignored during
00049 // transformation.  E.g. typically, there's no need to model main
00050 // memory.
00051 //
00052 // ====================================================================
00053 // ====================================================================
00054 
00055 #ifdef _KEEP_RCS_ID
00056 static const char source_file[] = __FILE__;
00057 #endif /* _KEEP_RCS_ID */
00058 
00059 #include <sys/types.h>
00060 #include <math.h>
00061 
00062 #include "defs.h"
00063 #include "errors.h"
00064 #include "config_cache.h"
00065 
00066 //---------------------------------------------------------------------------
00067 
00068 MHD_LEVEL::MHD_LEVEL(MHD_TYPE type, INT64 cs, INT32 ls,
00069                      INT32 cmp, INT32 dmp, INT32 assoc,
00070                      INT32 tlb_entries, INT32 ps,
00071                      INT32 tlb_cmp, INT32 tlb_dmp,
00072                      double outstanding,
00073                      double op_overlap_1, double op_overlap_2,
00074                      INT pct_xwrites_nonhidable) :
00075   Type(type), Size(cs), Line_Size(ls),
00076   Clean_Miss_Penalty(cmp), Dirty_Miss_Penalty(dmp), Associativity(assoc),
00077   TLB_Entries(tlb_entries), Page_Size(ps), Prefetch_Level (-1),
00078   TLB_Clean_Miss_Penalty(tlb_cmp), TLB_Dirty_Miss_Penalty(tlb_dmp),
00079   Typical_Outstanding(outstanding),
00080   Load_Op_Overlap_1(op_overlap_1),  Load_Op_Overlap_2(op_overlap_2),
00081   Pct_Excess_Writes_Nonhidable(pct_xwrites_nonhidable),
00082   CS_string (NULL), CMP_Set (FALSE), DMP_Set (FALSE),
00083   Is_Mem_Level(-1), Is_Mem_Level_Set(FALSE),
00084   Miss_Penalty(-1), Miss_Penalty_Set(FALSE),
00085   TLB_CMP_Set (FALSE), TLB_DMP_Set (FALSE),
00086   TLB_Miss_Penalty(-1), TLB_MP_Set(FALSE)
00087 {
00088   Compute_Effective_Size();
00089 }
00090 
00091 MHD_LEVEL& MHD_LEVEL::operator = (const MHD_LEVEL& a)
00092 {
00093   Type = a.Type;
00094   Line_Size = a.Line_Size;
00095   Size = a.Size;
00096   Clean_Miss_Penalty = a.Clean_Miss_Penalty;
00097   Dirty_Miss_Penalty = a.Dirty_Miss_Penalty;
00098   Associativity = a.Associativity;
00099   Effective_Size = a.Effective_Size;
00100   TLB_Entries = a.TLB_Entries;
00101   Page_Size = a.Page_Size;
00102   Prefetch_Level = a.Prefetch_Level;
00103   TLB_Clean_Miss_Penalty = a.TLB_Clean_Miss_Penalty;
00104   TLB_Dirty_Miss_Penalty = a.TLB_Dirty_Miss_Penalty;
00105   Typical_Outstanding = a.Typical_Outstanding;
00106   Load_Op_Overlap_1 = a.Load_Op_Overlap_1;
00107   Load_Op_Overlap_2 = a.Load_Op_Overlap_2;
00108   Pct_Excess_Writes_Nonhidable = a.Pct_Excess_Writes_Nonhidable;
00109 
00110   // The following are to be used only during option setting;
00111   // simply reset them to defaults:
00112   CS_string = NULL;
00113   CMP_Set = FALSE;
00114   DMP_Set = FALSE;
00115   Is_Mem_Level = -1;
00116   Is_Mem_Level_Set = FALSE;
00117   Miss_Penalty = -1;
00118   Miss_Penalty_Set = FALSE;
00119   TLB_CMP_Set = FALSE;
00120   TLB_DMP_Set = FALSE;
00121   TLB_Miss_Penalty = -1;
00122   TLB_MP_Set = FALSE;
00123   
00124   return *this;
00125 }
00126 
00127 BOOL MHD_LEVEL::Valid() const
00128 {
00129   return Size >= 1 &&
00130          Line_Size  >= 1 &&
00131          (Associativity >= 1 || Type == MHD_TYPE_MEM) &&
00132          Clean_Miss_Penalty >= 1 && Dirty_Miss_Penalty >= 1;
00133 }
00134 
00135 BOOL MHD_LEVEL::TLB_Valid() const
00136 {
00137   return TLB_Entries >= 1 &&
00138          Page_Size >= 1 &&
00139          TLB_Clean_Miss_Penalty >= 1 &&
00140          TLB_Dirty_Miss_Penalty >= 1 &&
00141          Valid();
00142 }
00143 
00144 void MHD_LEVEL::Merge_Options(const MHD_LEVEL& o)
00145 {
00146   BOOL recompute_ecs = FALSE;
00147   
00148   if (o.Type != MHD_TYPE_NONE) {
00149     Type = o.Type;
00150     recompute_ecs = TRUE;
00151   }
00152 
00153   if (o.Line_Size != -1) {
00154     Line_Size = o.Line_Size;
00155     recompute_ecs = TRUE;
00156   }
00157   if (o.Size != -1) {
00158     Size = o.Size;
00159     recompute_ecs = TRUE;
00160   }
00161   if (o.Associativity != -1) {
00162     Associativity = o.Associativity;
00163     recompute_ecs = TRUE;
00164   }
00165   if (o.Clean_Miss_Penalty != -1)
00166     Clean_Miss_Penalty = o.Clean_Miss_Penalty;
00167   if (o.Dirty_Miss_Penalty != -1)
00168     Dirty_Miss_Penalty = o.Dirty_Miss_Penalty;
00169 
00170   if (o.TLB_Entries != -1)
00171     TLB_Entries = o.TLB_Entries;
00172   if (o.Page_Size != -1)
00173     Page_Size = o.Page_Size;
00174   if (o.Prefetch_Level != -1)
00175     Prefetch_Level = o.Prefetch_Level;
00176   if (o.TLB_Clean_Miss_Penalty != -1)
00177     TLB_Clean_Miss_Penalty = o.TLB_Clean_Miss_Penalty;
00178   if (o.TLB_Dirty_Miss_Penalty != -1)
00179     TLB_Dirty_Miss_Penalty = o.TLB_Dirty_Miss_Penalty;
00180 
00181   if (o.Typical_Outstanding >= 0.0)
00182     Typical_Outstanding = o.Typical_Outstanding;
00183   if (o.Load_Op_Overlap_1 >= 0.0)
00184     Load_Op_Overlap_1 = o.Load_Op_Overlap_1;
00185   if (o.Load_Op_Overlap_2 >= 0.0)
00186     Load_Op_Overlap_2 = o.Load_Op_Overlap_2;
00187   if (o.Pct_Excess_Writes_Nonhidable >= 0)
00188     Pct_Excess_Writes_Nonhidable = o.Pct_Excess_Writes_Nonhidable;
00189 
00190   if (Valid() && recompute_ecs)
00191     Compute_Effective_Size();
00192 }
00193 
00194 void MHD_LEVEL::Compute_Effective_Size()
00195 {
00196   // Make the effective cache fraction increases by 2% per 10x decrease in
00197   // cache size.  5% per 10x decrease in
00198   // line size, and 8% per 10x decrease of assoc.  Also, if it drops
00199   // below 7%, move it half way towards 7% and don't let it drop below
00200   // 3.5% (a real anomaly, but the user can specify any oddball cache).
00201   // Basis is 16% for a 64kB direct mapped cache with 16b lines.
00202 
00203   // For a memory, the associativity (and all other parameters, come to
00204   // think of it) are ignored, and we use use the effective cache size
00205   // as 90% of the cache.  (conservative, in case I miscomputed the area,
00206   // better to err on that side).
00207 
00208   double pct;
00209   
00210   switch (Type) {
00211    case MHD_TYPE_MEM:
00212     pct = 0.9;
00213     break;
00214    case MHD_TYPE_CACHE:
00215     pct = 0.16 - 0.02*log10(double(Size)/(64*1024))
00216                - 0.05*log10(double(Line_Size)/16)
00217                + 0.07*log10(double(MIN(Associativity,64)));
00218 
00219     if (pct < 0.0)
00220       pct = 0.035;
00221     else if (pct <= 0.07)
00222       pct += (0.07 - pct)/2;
00223     else if (pct > 0.50)
00224       pct = 0.50;
00225     break;
00226   }
00227 
00228   Effective_Size = pct*Size;
00229 }
00230 
00231 void MHD_LEVEL::Print(FILE* f) const
00232 {
00233   fprintf(f, "sz=%lld(%lld,%.1f%%)\n", 
00234           Size, Effective_Size, 100.0*Effective_Size/Size);
00235   fprintf(f, "  ls=%d cmp=%d dmp=%d\n", 
00236           Line_Size, Clean_Miss_Penalty, Dirty_Miss_Penalty);
00237   if (Type == MHD_TYPE_MEM)
00238     fprintf(f, "<mem> ");
00239   else
00240     fprintf(f, "  a=%d ", Associativity);
00241   fprintf(f, "tlbsz=%d ps=%d tlbcmp=%d tlbdmp=%d\n",
00242           TLB_Entries, Page_Size,
00243           TLB_Clean_Miss_Penalty, TLB_Dirty_Miss_Penalty);
00244   fprintf(f, "  out=%g, ovlp1=%g, ovlp2=%g\n",
00245           Typical_Outstanding, Load_Op_Overlap_1, Load_Op_Overlap_2);
00246 }
00247 
00248 //---------------------------------------------------------------------------
00249 
00250 MHD Mhd;
00251 MHD Mhd_Options;
00252 
00253 //---------------------------------------------------------------------------
00254 
00255 INT MHD::Next(INT i)
00256 {
00257   if (i != -1) {
00258     for (i++; i < MHD_MAX_LEVELS; i++) {
00259       if (L[i].Valid())
00260         return i;
00261     }
00262   }
00263   return -1;
00264 }
00265 
00266 INT MHD::First()
00267 {
00268   for (INT i = 0; i < MHD_MAX_LEVELS; i++) {
00269     if (L[i].Valid())
00270       return i;
00271   }
00272   return -1;
00273 }
00274 
00275 void MHD::Merge_Options(const MHD& o)
00276 {
00277   for (INT i = 0; i < MHD_MAX_LEVELS; i++)
00278     L[i].Merge_Options(o.L[i]);
00279 
00280   if (o.Non_Blocking_Loads != -1)
00281     Non_Blocking_Loads = o.Non_Blocking_Loads;
00282   if (o.Loop_Overhead_Base >= 0)
00283     Loop_Overhead_Base = o.Loop_Overhead_Base;
00284   if (o.Loop_Overhead_Memref >= 0)
00285     Loop_Overhead_Memref = o.Loop_Overhead_Memref;
00286 }
00287 
00288 void MHD::Print(FILE* f) const
00289 {
00290   fprintf(f, "CACHE PARAMETERS: non_blocking_loads=%d loop_overhead=(%d,%d)\n",
00291           Non_Blocking_Loads, Loop_Overhead_Base, Loop_Overhead_Memref);
00292   for (INT i = 0; i < MHD_MAX_LEVELS; i++) {
00293     if (L[i].Valid()) {
00294       fprintf(f, "L[%d]: ", i);
00295       L[i].Print(f);
00296     }
00297   }
00298   fprintf(f, "\n"); 
00299 }
00300 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines