00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #ifdef _KEEP_RCS_ID
00056 static const char source_file[] = __FILE__;
00057 #endif
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
00111
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
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
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