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
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifdef _KEEP_RCS_ID
00065 static const char source_file[] = __FILE__;
00066 #endif
00067
00068 #include <sys/types.h>
00069 #include <math.h>
00070
00071 #include "defs.h"
00072 #include "errors.h"
00073 #include "config_cache.h"
00074 #ifdef KEY
00075 #include "config_lno.h"
00076 #endif
00077
00078
00079
00080 MHD_LEVEL::MHD_LEVEL(MHD_TYPE type, INT64 cs, INT32 ls,
00081 INT32 cmp, INT32 dmp, INT32 assoc,
00082 INT32 tlb_entries, INT32 ps,
00083 INT32 tlb_cmp, INT32 tlb_dmp,
00084 double outstanding,
00085 double op_overlap_1, double op_overlap_2,
00086 INT pct_xwrites_nonhidable) :
00087 Type(type), Size(cs), Line_Size(ls),
00088 Clean_Miss_Penalty(cmp), Dirty_Miss_Penalty(dmp), Associativity(assoc),
00089 TLB_Entries(tlb_entries), Page_Size(ps), Prefetch_Level (-1),
00090 TLB_Clean_Miss_Penalty(tlb_cmp), TLB_Dirty_Miss_Penalty(tlb_dmp),
00091 Typical_Outstanding(outstanding),
00092 Load_Op_Overlap_1(op_overlap_1), Load_Op_Overlap_2(op_overlap_2),
00093 Pct_Excess_Writes_Nonhidable(pct_xwrites_nonhidable),
00094 CS_string (NULL), CMP_Set (FALSE), DMP_Set (FALSE),
00095 Is_Mem_Level(-1), Is_Mem_Level_Set(FALSE),
00096 Miss_Penalty(-1), Miss_Penalty_Set(FALSE),
00097 TLB_CMP_Set (FALSE), TLB_DMP_Set (FALSE),
00098 TLB_Miss_Penalty(-1), TLB_MP_Set(FALSE)
00099 {
00100 Compute_Effective_Size();
00101 }
00102
00103 void MHD_LEVEL::operator = (const MHD_LEVEL& a)
00104 {
00105 Type = a.Type;
00106 Line_Size = a.Line_Size;
00107 Size = a.Size;
00108 Clean_Miss_Penalty = a.Clean_Miss_Penalty;
00109 Dirty_Miss_Penalty = a.Dirty_Miss_Penalty;
00110 Associativity = a.Associativity;
00111 Effective_Size = a.Effective_Size;
00112 TLB_Entries = a.TLB_Entries;
00113 Page_Size = a.Page_Size;
00114 Prefetch_Level = a.Prefetch_Level;
00115 TLB_Clean_Miss_Penalty = a.TLB_Clean_Miss_Penalty;
00116 TLB_Dirty_Miss_Penalty = a.TLB_Dirty_Miss_Penalty;
00117 Typical_Outstanding = a.Typical_Outstanding;
00118 Load_Op_Overlap_1 = a.Load_Op_Overlap_1;
00119 Load_Op_Overlap_2 = a.Load_Op_Overlap_2;
00120 Pct_Excess_Writes_Nonhidable = a.Pct_Excess_Writes_Nonhidable;
00121
00122
00123
00124 CS_string = NULL;
00125 CMP_Set = FALSE;
00126 DMP_Set = FALSE;
00127 Is_Mem_Level = -1;
00128 Is_Mem_Level_Set = FALSE;
00129 Miss_Penalty = -1;
00130 Miss_Penalty_Set = FALSE;
00131 TLB_CMP_Set = FALSE;
00132 TLB_DMP_Set = FALSE;
00133 TLB_Miss_Penalty = -1;
00134 TLB_MP_Set = FALSE;
00135 }
00136
00137 BOOL MHD_LEVEL::Valid() const
00138 {
00139 return Size >= 1 &&
00140 Line_Size >= 1 &&
00141 (Associativity >= 1 || Type == MHD_TYPE_MEM) &&
00142 Clean_Miss_Penalty >= 1 && Dirty_Miss_Penalty >= 1;
00143 }
00144
00145 BOOL MHD_LEVEL::TLB_Valid() const
00146 {
00147 return TLB_Entries >= 1 &&
00148 Page_Size >= 1 &&
00149 TLB_Clean_Miss_Penalty >= 1 &&
00150 TLB_Dirty_Miss_Penalty >= 1 &&
00151 Valid();
00152 }
00153
00154 void MHD_LEVEL::Merge_Options(const MHD_LEVEL& o)
00155 {
00156 BOOL recompute_ecs = FALSE;
00157
00158 if (o.Type != MHD_TYPE_NONE) {
00159 Type = o.Type;
00160 recompute_ecs = TRUE;
00161 }
00162
00163 if (o.Line_Size != -1) {
00164 Line_Size = o.Line_Size;
00165 recompute_ecs = TRUE;
00166 }
00167 if (o.Size != -1) {
00168 Size = o.Size;
00169 recompute_ecs = TRUE;
00170 }
00171 if (o.Associativity != -1) {
00172 Associativity = o.Associativity;
00173 recompute_ecs = TRUE;
00174 }
00175 if (o.Clean_Miss_Penalty != -1)
00176 Clean_Miss_Penalty = o.Clean_Miss_Penalty;
00177 if (o.Dirty_Miss_Penalty != -1)
00178 Dirty_Miss_Penalty = o.Dirty_Miss_Penalty;
00179
00180 if (o.TLB_Entries != -1)
00181 TLB_Entries = o.TLB_Entries;
00182 if (o.Page_Size != -1)
00183 Page_Size = o.Page_Size;
00184 if (o.Prefetch_Level != -1)
00185 Prefetch_Level = o.Prefetch_Level;
00186 if (o.TLB_Clean_Miss_Penalty != -1)
00187 TLB_Clean_Miss_Penalty = o.TLB_Clean_Miss_Penalty;
00188 if (o.TLB_Dirty_Miss_Penalty != -1)
00189 TLB_Dirty_Miss_Penalty = o.TLB_Dirty_Miss_Penalty;
00190
00191 if (o.Typical_Outstanding >= 0.0)
00192 Typical_Outstanding = o.Typical_Outstanding;
00193 if (o.Load_Op_Overlap_1 >= 0.0)
00194 Load_Op_Overlap_1 = o.Load_Op_Overlap_1;
00195 if (o.Load_Op_Overlap_2 >= 0.0)
00196 Load_Op_Overlap_2 = o.Load_Op_Overlap_2;
00197 if (o.Pct_Excess_Writes_Nonhidable >= 0)
00198 Pct_Excess_Writes_Nonhidable = o.Pct_Excess_Writes_Nonhidable;
00199
00200 if (Valid() && recompute_ecs)
00201 Compute_Effective_Size();
00202 #ifdef KEY
00203 if(Valid())
00204 Reset_CS_String();
00205 #endif
00206 }
00207
00208 #ifdef KEY
00209 void MHD_LEVEL::Reset_CS_String()
00210 {
00211 if(Size < 0) return;
00212 if(CS_string != NULL)
00213 free(CS_string);
00214 const char *addition = "K";
00215 INT64 remains = Size/1024;
00216 if(remains >= 1024)
00217 {
00218 addition = "M";
00219 remains = remains/1024;
00220 if(remains >= 1024){
00221 remains = remains/1024;
00222 addition = "G";
00223 }
00224 }
00225 CS_string = (char *)malloc(32);
00226 sprintf(CS_string, "%lld", remains);
00227 strcat(CS_string, addition);
00228 }
00229 #endif
00230
00231 void MHD_LEVEL::Compute_Effective_Size()
00232 {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 double pct;
00246
00247 switch (Type) {
00248 case MHD_TYPE_MEM:
00249 pct = 0.9;
00250 break;
00251 case MHD_TYPE_CACHE:
00252 pct = 0.16 - 0.02*log10(double(Size)/(64*1024))
00253 - 0.05*log10(double(Line_Size)/16)
00254 + 0.07*log10(double(MIN(Associativity,64)));
00255
00256 if (pct < 0.0)
00257 pct = 0.035;
00258 else if (pct <= 0.07)
00259 pct += (0.07 - pct)/2;
00260 else if (pct > 0.50)
00261 pct = 0.50;
00262 break;
00263 }
00264
00265 Effective_Size = (INT64) (pct*Size);
00266 #ifdef KEY
00267 if (LNO_EffectiveCacheSizePct != 0)
00268 Effective_Size = (INT64) ((double)LNO_EffectiveCacheSizePct/100.0*Size);
00269 #endif
00270 }
00271
00272 void MHD_LEVEL::Print(FILE* f) const
00273 {
00274 fprintf(f, "sz=%lld(%lld,%.1f%%)\n",
00275 Size, Effective_Size, 100.0*Effective_Size/Size);
00276 fprintf(f, " ls=%d cmp=%d dmp=%d\n",
00277 Line_Size, Clean_Miss_Penalty, Dirty_Miss_Penalty);
00278 if (Type == MHD_TYPE_MEM)
00279 fprintf(f, "<mem> ");
00280 else
00281 fprintf(f, " a=%d ", Associativity);
00282 fprintf(f, "tlbsz=%d ps=%d tlbcmp=%d tlbdmp=%d\n",
00283 TLB_Entries, Page_Size,
00284 TLB_Clean_Miss_Penalty, TLB_Dirty_Miss_Penalty);
00285 fprintf(f, " out=%g, ovlp1=%g, ovlp2=%g\n",
00286 Typical_Outstanding, Load_Op_Overlap_1, Load_Op_Overlap_2);
00287 }
00288
00289
00290
00291 MHD Mhd;
00292 MHD Mhd_Options;
00293
00294
00295
00296 INT MHD::Next(INT i)
00297 {
00298 if (i != -1) {
00299 for (i++; i < MHD_MAX_LEVELS; i++) {
00300 if (L[i].Valid())
00301 return i;
00302 }
00303 }
00304 return -1;
00305 }
00306
00307 INT MHD::First()
00308 {
00309 for (INT i = 0; i < MHD_MAX_LEVELS; i++) {
00310 if (L[i].Valid())
00311 return i;
00312 }
00313 return -1;
00314 }
00315
00316 void MHD::Merge_Options(const MHD& o)
00317 {
00318 for (INT i = 0; i < MHD_MAX_LEVELS; i++)
00319 L[i].Merge_Options(o.L[i]);
00320
00321 if (o.Non_Blocking_Loads != -1)
00322 Non_Blocking_Loads = o.Non_Blocking_Loads;
00323 if (o.Loop_Overhead_Base >= 0)
00324 Loop_Overhead_Base = o.Loop_Overhead_Base;
00325 if (o.Loop_Overhead_Memref >= 0)
00326 Loop_Overhead_Memref = o.Loop_Overhead_Memref;
00327 #ifdef KEY
00328 if (o.TLB_Trustworthiness >= 0)
00329 TLB_Trustworthiness = o.TLB_Trustworthiness;
00330 #endif
00331 }
00332
00333 void MHD::Print(FILE* f) const
00334 {
00335 fprintf(f, "CACHE PARAMETERS: non_blocking_loads=%d loop_overhead=(%d,%d)\n",
00336 Non_Blocking_Loads, Loop_Overhead_Base, Loop_Overhead_Memref);
00337 for (INT i = 0; i < MHD_MAX_LEVELS; i++) {
00338 if (L[i].Valid()) {
00339 fprintf(f, "L[%d]: ", i);
00340 L[i].Print(f);
00341 }
00342 }
00343 fprintf(f, "\n");
00344 }
00345