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 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028
00029 #include <stdio.h>
00030
00031 #include "auxlry.h"
00032 #include "cell_xsb.h"
00033 #include "psc_xsb.h"
00034 #include "table_stats.h"
00035 #include "trie_internals.h"
00036 #include "macro_xsb.h"
00037 #include "error_xsb.h"
00038 #include "flags_xsb.h"
00039 #include "debug_xsb.h"
00040 #include "thread_xsb.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 NodeStats node_statistics(Structure_Manager *sm) {
00057
00058 NodeStats stats;
00059
00060
00061 SM_CurrentCapacity(*sm, NodeStats_NumBlocks(stats),
00062 NodeStats_NumAllocNodes(stats));
00063 SM_CountFreeStructs(*sm, NodeStats_NumFreeNodes(stats));
00064 NodeStats_NodeSize(stats) = SM_StructSize(*sm);
00065
00066 return stats;
00067 }
00068
00069
00070
00071 HashStats hash_statistics(Structure_Manager *sm) {
00072
00073 HashStats ht_stats;
00074 counter num_used_hdrs;
00075 BTHTptr pBTHT;
00076 BTNptr *ppBTN;
00077
00078
00079 ht_stats.hdr = node_statistics(sm);
00080
00081 num_used_hdrs = 0;
00082 HashStats_NumBuckets(ht_stats) = 0;
00083 HashStats_TotalOccupancy(ht_stats) = 0;
00084 HashStats_NonEmptyBuckets(ht_stats) = 0;
00085 HashStats_BucketSize(ht_stats) = sizeof(void *);
00086 pBTHT = (BTHTptr)SM_AllocList(*sm);
00087 while ( IsNonNULL(pBTHT) ) {
00088 #ifdef DEBUG_ASSERTIONS
00089
00090
00091 counter num_contents = 0;
00092 #endif
00093 num_used_hdrs++;
00094 HashStats_NumBuckets(ht_stats) += BTHT_NumBuckets(pBTHT);
00095 HashStats_TotalOccupancy(ht_stats) += BTHT_NumContents(pBTHT);
00096 for ( ppBTN = BTHT_BucketArray(pBTHT);
00097 ppBTN < BTHT_BucketArray(pBTHT) + BTHT_NumBuckets(pBTHT);
00098 ppBTN++ )
00099 if ( IsNonNULL(*ppBTN) ) {
00100 #ifdef DEBUG_ASSERTIONS
00101
00102
00103 BTNptr pBTN = *ppBTN;
00104 do {
00105 num_contents++;
00106 pBTN = BTN_Sibling(pBTN);
00107 } while ( IsNonNULL(pBTN) );
00108 #endif
00109 HashStats_NonEmptyBuckets(ht_stats)++;
00110 }
00111 #ifdef DEBUG_ASSERTIONS
00112
00113
00114 if ( num_contents != BTHT_NumContents(pBTHT) )
00115 xsb_warn("Inconsistent %s Usage Calculations:\n"
00116 "\tHash table occupancy mismatch.", SM_StructName(*sm));
00117 #endif
00118 pBTHT = BTHT_NextBTHT(pBTHT);
00119 }
00120 if ( HashStats_NumAllocHeaders(ht_stats) !=
00121 (num_used_hdrs + HashStats_NumFreeHeaders(ht_stats)) )
00122 xsb_warn("Inconsistent %s Usage Calculations:\n"
00123 "\tHeader count mismatch: Alloc: %d Used: %d Free: %d",
00124 SM_StructName(*sm), HashStats_NumAllocHeaders(ht_stats),
00125 num_used_hdrs, HashStats_NumFreeHeaders(ht_stats));
00126
00127 return ht_stats;
00128 }
00129
00130
00131
00132
00133 NodeStats subgoal_statistics(CTXTdeclc Structure_Manager *sm) {
00134
00135 NodeStats sg_stats;
00136 TIFptr tif;
00137 int nSubgoals;
00138 VariantSF pProdSF;
00139 SubConsSF pConsSF;
00140
00141 sg_stats = node_statistics(sm);
00142 nSubgoals = 0;
00143 SYS_MUTEX_LOCK( MUTEX_TABLE );
00144 if ( sm == &smVarSF ) {
00145 for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) )
00146 if ( IsVariantPredicate(tif) )
00147 for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF);
00148 pProdSF = (VariantSF)subg_next_subgoal(pProdSF) )
00149 nSubgoals++;
00150 }
00151
00152 else if ( sm == &smProdSF ) {
00153 for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) )
00154 if ( IsSubsumptivePredicate(tif) )
00155 for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF);
00156 pProdSF = (VariantSF)subg_next_subgoal(pProdSF) )
00157 nSubgoals++;
00158 }
00159 else if ( sm == &smConsSF ) {
00160 for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) )
00161 if ( IsSubsumptivePredicate(tif) )
00162 for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF);
00163 pProdSF = (VariantSF)subg_next_subgoal(pProdSF) )
00164 for ( pConsSF = subg_consumers(pProdSF); IsNonNULL(pConsSF);
00165 pConsSF = conssf_consumers(pConsSF) )
00166 nSubgoals++;
00167 }
00168 else {
00169 SYS_MUTEX_UNLOCK( MUTEX_TABLE );
00170 xsb_dbgmsg((LOG_DEBUG, "Incorrect use of subgoal_statistics()\n"
00171 "SM does not contain subgoal frames"));
00172 return sg_stats;
00173 }
00174
00175 SYS_MUTEX_UNLOCK( MUTEX_TABLE );
00176 if ( NodeStats_NumUsedNodes(sg_stats) != (counter) nSubgoals )
00177 xsb_warn("Inconsistent Subgoal Frame Usage Calculations:\n"
00178 "\tSubgoal Frame count mismatch");
00179
00180 return sg_stats;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190 void print_detailed_tablespace_stats(CTXTdecl) {
00191
00192 NodeStats
00193 btn,
00194 tstn,
00195 aln,
00196 tsi,
00197 varsf,
00198 prodsf,
00199 conssf;
00200
00201 HashStats
00202 btht,
00203 tstht;
00204
00205
00206 btn = node_statistics(&smTableBTN);
00207 btht = hash_statistics(&smTableBTHT);
00208 varsf = subgoal_statistics(CTXTc &smVarSF);
00209 prodsf = subgoal_statistics(CTXTc &smProdSF);
00210 conssf = subgoal_statistics(CTXTc &smConsSF);
00211 aln = node_statistics(&smALN);
00212 tstn = node_statistics(&smTSTN);
00213 tstht = hash_statistics(&smTSTHT);
00214 tsi = node_statistics(&smTSIN);
00215
00216 printf("\n"
00217 "Table Space Usage\n");
00218 printf(" Current Total Allocation: %12u bytes\n"
00219 " Current Total Usage: %12u bytes\n",
00220 CurrentTotalTableSpaceAlloc(btn,btht,varsf,prodsf,conssf,aln,
00221 tstn,tstht,tsi),
00222 CurrentTotalTableSpaceUsed(btn,btht,varsf,prodsf,conssf,aln,
00223 tstn,tstht,tsi));
00224 printf("\n"
00225 " Basic Tries\n");
00226 printf(" Basic Trie Nodes (%u blocks)\n"
00227 " Allocated: %10u (%8u bytes)\n"
00228 " Used: %10u (%8u bytes)\n"
00229 " Free: %10u (%8u bytes)\n",
00230 NodeStats_NumBlocks(btn),
00231 NodeStats_NumAllocNodes(btn), NodeStats_SizeAllocNodes(btn),
00232 NodeStats_NumUsedNodes(btn), NodeStats_SizeUsedNodes(btn),
00233 NodeStats_NumFreeNodes(btn), NodeStats_SizeFreeNodes(btn));
00234 printf(" Basic Trie Hash Tables (%u blocks)\n"
00235 " Headers: %10u (%8u bytes)\n"
00236 " Used: %10u (%8u bytes)\n"
00237 " Free: %10u (%8u bytes)\n"
00238 " Buckets: %10u (%8u bytes)\n"
00239 " Used: %10u\n"
00240 " Empty: %10u\n"
00241 " Occupancy: %10u BTNs\n",
00242 HashStats_NumBlocks(btht),
00243 HashStats_NumAllocHeaders(btht), HashStats_SizeAllocHeaders(btht),
00244 HashStats_NumUsedHeaders(btht), HashStats_SizeUsedHeaders(btht),
00245 HashStats_NumFreeHeaders(btht), HashStats_SizeFreeHeaders(btht),
00246 HashStats_NumBuckets(btht), HashStats_SizeAllocBuckets(btht),
00247 HashStats_NonEmptyBuckets(btht), HashStats_EmptyBuckets(btht),
00248 HashStats_TotalOccupancy(btht));
00249 printf("\n"
00250 " Subgoal Frames\n"
00251 " Variant Subgoal Frames (%u blocks)\n"
00252 " Allocated: %10u (%8u bytes)\n"
00253 " Used: %10u (%8u bytes)\n"
00254 " Free: %10u (%8u bytes)\n"
00255 " Subsumptive Producer Subgoal Frames (%u blocks)\n"
00256 " Allocated: %10u (%8u bytes)\n"
00257 " Used: %10u (%8u bytes)\n"
00258 " Free: %10u (%8u bytes)\n"
00259 " Subsumptive Consumer Subgoal Frames (%u blocks)\n"
00260 " Allocated: %10u (%8u bytes)\n"
00261 " Used: %10u (%8u bytes)\n"
00262 " Free: %10u (%8u bytes)\n",
00263 NodeStats_NumBlocks(varsf),
00264 NodeStats_NumAllocNodes(varsf), NodeStats_SizeAllocNodes(varsf),
00265 NodeStats_NumUsedNodes(varsf), NodeStats_SizeUsedNodes(varsf),
00266 NodeStats_NumFreeNodes(varsf), NodeStats_SizeFreeNodes(varsf),
00267 NodeStats_NumBlocks(prodsf),
00268 NodeStats_NumAllocNodes(prodsf), NodeStats_SizeAllocNodes(prodsf),
00269 NodeStats_NumUsedNodes(prodsf), NodeStats_SizeUsedNodes(prodsf),
00270 NodeStats_NumFreeNodes(prodsf), NodeStats_SizeFreeNodes(prodsf),
00271 NodeStats_NumBlocks(conssf),
00272 NodeStats_NumAllocNodes(conssf), NodeStats_SizeAllocNodes(conssf),
00273 NodeStats_NumUsedNodes(conssf), NodeStats_SizeUsedNodes(conssf),
00274 NodeStats_NumFreeNodes(conssf), NodeStats_SizeFreeNodes(conssf));
00275 printf("\n"
00276 " Answer List Nodes (%u blocks)\n"
00277 " Allocated: %10u (%8u bytes)\n"
00278 " Used: %10u (%8u bytes)\n"
00279 " Free: %10u (%8u bytes)\n",
00280 NodeStats_NumBlocks(aln),
00281 NodeStats_NumAllocNodes(aln), NodeStats_SizeAllocNodes(aln),
00282 NodeStats_NumUsedNodes(aln), NodeStats_SizeUsedNodes(aln),
00283 NodeStats_NumFreeNodes(aln), NodeStats_SizeFreeNodes(aln));
00284 printf("\n"
00285 " Time Stamp Tries\n"
00286 " Time Stamp Trie Nodes (%u blocks)\n"
00287 " Allocated: %10u (%8u bytes)\n"
00288 " Used: %10u (%8u bytes)\n"
00289 " Free: %10u (%8u bytes)\n",
00290 NodeStats_NumBlocks(tstn),
00291 NodeStats_NumAllocNodes(tstn), NodeStats_SizeAllocNodes(tstn),
00292 NodeStats_NumUsedNodes(tstn), NodeStats_SizeUsedNodes(tstn),
00293 NodeStats_NumFreeNodes(tstn) , NodeStats_SizeFreeNodes(tstn));
00294 printf(" Time Stamp Trie Hash Tables (%u blocks)\n"
00295 " Headers: %10u (%8u bytes)\n"
00296 " Used: %10u (%8u bytes)\n"
00297 " Free: %10u (%8u bytes)\n"
00298 " Buckets: %10u (%8u bytes)\n"
00299 " Used: %10u\n"
00300 " Empty: %10u\n"
00301 " Occupancy: %10u TSTNs\n",
00302 HashStats_NumBlocks(tstht),
00303 HashStats_NumAllocHeaders(tstht), HashStats_SizeAllocHeaders(tstht),
00304 HashStats_NumUsedHeaders(tstht), HashStats_SizeUsedHeaders(tstht),
00305 HashStats_NumFreeHeaders(tstht), HashStats_SizeFreeHeaders(tstht),
00306 HashStats_NumBuckets(tstht), HashStats_SizeAllocBuckets(tstht),
00307 HashStats_NonEmptyBuckets(tstht), HashStats_EmptyBuckets(tstht),
00308 HashStats_TotalOccupancy(tstht));
00309 printf(" Time Stamp Trie Index Nodes (%u blocks)\n"
00310 " Allocated: %10u (%8u bytes)\n"
00311 " Used: %10u (%8u bytes)\n"
00312 " Free: %10u (%8u bytes)\n",
00313 NodeStats_NumBlocks(tsi),
00314 NodeStats_NumAllocNodes(tsi), NodeStats_SizeAllocNodes(tsi),
00315 NodeStats_NumUsedNodes(tsi), NodeStats_SizeUsedNodes(tsi),
00316 NodeStats_NumFreeNodes(tsi), NodeStats_SizeFreeNodes(tsi));
00317
00318 if (flags[TRACE_STA]) {
00319
00320
00321 update_maximum_tablespace_stats(&btn,&btht,&varsf,&prodsf,&conssf,
00322 &aln,&tstn,&tstht,&tsi);
00323 printf("\n"
00324 "Maximum Total Usage: %12ld bytes\n",
00325 maximum_total_tablespace_usage());
00326 printf("Maximum Structure Usage:\n"
00327 " ALNs: %10u (%8u bytes)\n"
00328 " TSINs: %10u (%8u bytes)\n",
00329 maximum_answer_list_nodes(),
00330 maximum_answer_list_nodes() * NodeStats_NodeSize(aln),
00331 maximum_timestamp_index_nodes(),
00332 maximum_timestamp_index_nodes() * NodeStats_NodeSize(tsi));
00333 }
00334 printf("\n");
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 struct {
00361 counter tsi;
00362 counter alns;
00363 unsigned long total_bytes;
00364 } maxTableSpaceUsage = {0,0,0};
00365
00366
00367
00368
00369 void reset_maximum_tablespace_stats() {
00370
00371 maxTableSpaceUsage.tsi = maxTableSpaceUsage.alns = 0;
00372 maxTableSpaceUsage.total_bytes = 0;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 void compute_maximum_tablespace_stats(CTXTdecl) {
00386
00387 NodeStats tstn, btn, aln, tsi;
00388 NodeStats varsf, prodsf, conssf;
00389 HashStats tstht, btht;
00390
00391 btn = node_statistics(&smTableBTN);
00392 btht = hash_statistics(&smTableBTHT);
00393 varsf = subgoal_statistics(CTXTc &smVarSF);
00394 prodsf = subgoal_statistics(CTXTc &smProdSF);
00395 conssf = subgoal_statistics(CTXTc &smConsSF);
00396 tstn = node_statistics(&smTSTN);
00397 tstht = hash_statistics(&smTSTHT);
00398 tsi = node_statistics(&smTSIN);
00399 aln = node_statistics(&smALN);
00400
00401 update_maximum_tablespace_stats(&btn,&btht,&varsf,&prodsf,&conssf,
00402 &aln,&tstn,&tstht,&tsi);
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 void update_maximum_tablespace_stats(NodeStats *btn, HashStats *btht,
00416 NodeStats *varsf, NodeStats *prodsf,
00417 NodeStats *conssf, NodeStats *aln,
00418 NodeStats *tstn, HashStats *tstht,
00419 NodeStats *tsi) {
00420 unsigned long byte_size;
00421
00422 byte_size = CurrentTotalTableSpaceUsed(*btn,*btht,*varsf,*prodsf,*conssf,
00423 *aln,*tstn,*tstht,*tsi);
00424 if ( byte_size > maxTableSpaceUsage.total_bytes )
00425 maxTableSpaceUsage.total_bytes = byte_size;
00426 if ( NodeStats_NumUsedNodes(*aln) > maxTableSpaceUsage.alns )
00427 maxTableSpaceUsage.alns = NodeStats_NumUsedNodes(*aln);
00428 if ( NodeStats_NumUsedNodes(*tsi) > maxTableSpaceUsage.tsi )
00429 maxTableSpaceUsage.tsi = NodeStats_NumUsedNodes(*tsi);
00430 }
00431
00432
00433
00434 counter maximum_timestamp_index_nodes() {
00435
00436 return (maxTableSpaceUsage.tsi);
00437 }
00438
00439
00440
00441 counter maximum_answer_list_nodes() {
00442
00443 return (maxTableSpaceUsage.alns);
00444 }
00445
00446
00447
00448 unsigned long maximum_total_tablespace_usage() {
00449
00450 return (maxTableSpaceUsage.total_bytes);
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 NumSubOps numSubOps = INIT_NUMSUBOPS;
00461
00462
00463 void reset_subsumption_stats() {
00464
00465 NumSubOps initRecord = INIT_NUMSUBOPS;
00466
00467 numSubOps = initRecord;
00468 }
00469
00470
00471 void print_detailed_subsumption_stats() {
00472
00473 printf("Subsumptive Operations\n"
00474 " Subsumptive call check/insert ops: %8u\n"
00475 " * Calls to nonexistent or incomplete tables\n"
00476 " - Producers: %6u\n"
00477 " - Variants of producers: %6u\n"
00478 " - Properly subsumed: %6u\n"
00479 " Resulted in call table entry: %u\n"
00480 " * Calls to completed tables: %6u\n",
00481 NumSubOps_CallCheckInsert, NumSubOps_ProducerCall,
00482 NumSubOps_VariantCall, NumSubOps_SubsumedCall,
00483 NumSubOps_SubsumedCallEntry, NumSubOps_CallToCompletedTable);
00484 printf(" Answer check/insert operations: %8u\n"
00485 " * Actual answer inserts: %6u\n"
00486 " * Derivation ratio (New/Total): %4.2f\n",
00487 NumSubOps_AnswerCheckInsert, NumSubOps_AnswerInsert,
00488 ( (NumSubOps_AnswerCheckInsert != 0)
00489 ? (float)NumSubOps_AnswerInsert / (float)NumSubOps_AnswerCheckInsert
00490 : 0 ));
00491 printf(" Relevant-answer identify ops: %8u\n"
00492 " Answer-list consumption ops: %8u\n",
00493 NumSubOps_IdentifyRelevantAnswers, NumSubOps_AnswerConsumption);
00494 }
00495
00496