X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FProfiling.c;h=bec04fe51f504b2c5936ff9dc2e7d6f2924626cb;hb=4bd153f2dd93745183584054e17c6ff169691a49;hp=da6ad0beff888e13b855b88621820e2f5703184e;hpb=9469779a0b2d08d2c4cbf11d90fe31d600a5f683;p=ghc-hetmet.git diff --git a/ghc/rts/Profiling.c b/ghc/rts/Profiling.c index da6ad0b..bec04fe 100644 --- a/ghc/rts/Profiling.c +++ b/ghc/rts/Profiling.c @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: Profiling.c,v 1.26 2001/11/22 16:33:06 simonmar Exp $ * * (c) The GHC Team, 1998-2000 * @@ -16,12 +15,14 @@ #include "Profiling.h" #include "Storage.h" #include "Proftimer.h" -#include "Itimer.h" +#include "Timer.h" #include "ProfHeap.h" #include "Arena.h" #include "RetainerProfile.h" #include "LdvProfile.h" +#include + /* * Profiling allocation arena. */ @@ -36,24 +37,10 @@ unsigned int CC_ID; unsigned int CCS_ID; unsigned int HP_ID; -/* Table sizes from old profiling system. Not sure if we'll need - * these. - */ -nat time_intervals = 0; -nat earlier_ticks = 0; -nat max_cc_no = 0; -nat max_mod_no = 0; -nat max_grp_no = 0; -nat max_descr_no = 0; -nat max_type_no = 0; - -/* Are we time-profiling? - */ -rtsBool time_profiling = rtsFalse; - /* figures for the profiling report. */ -static lnat total_alloc, total_prof_ticks; +static ullong total_alloc; +static lnat total_prof_ticks; /* Globals for opening the profiling log file(s) */ @@ -143,13 +130,12 @@ static CostCentreStack * ActualPush ( CostCentreStack *, CostCentre * ); static CostCentreStack * IsInIndexTable ( IndexTable *, CostCentre * ); static IndexTable * AddToIndexTable ( IndexTable *, CostCentreStack *, CostCentre *, unsigned int ); +static void ccsSetSelected ( CostCentreStack *ccs ); +static void initTimeProfiling ( void ); +static void initProfilingLogFile( void ); - -static void initTimeProfiling ( void ); -static void initProfilingLogFile( void ); - -static void reportCCS_XML ( CostCentreStack *ccs ); +static void reportCCS_XML ( CostCentreStack *ccs ); /* ----------------------------------------------------------------------------- Initialise the profiling environment @@ -194,15 +180,6 @@ initProfiling1 (void) /* cost centres are registered by the per-module * initialisation code now... */ - - switch (RtsFlags.ProfFlags.doHeapProfile) { - case HEAP_BY_RETAINER: - initRetainerProfiling(); - break; - case HEAP_BY_LDV: - initLdvProfiling(); - break; - } } void @@ -221,7 +198,9 @@ initProfiling2 (void) */ ASSERT(CCS_MAIN->prevStack == 0); CCS_MAIN->root = CC_MAIN; + ccsSetSelected(CCS_MAIN); DecCCS(CCS_MAIN); + for (ccs = CCS_LIST; ccs != CCS_MAIN; ) { next = ccs->prevStack; ccs->prevStack = 0; @@ -238,24 +217,59 @@ initProfiling2 (void) initHeapProfiling(); } } - + +// Decide whether closures with this CCS should contribute to the heap +// profile. +static void +ccsSetSelected( CostCentreStack *ccs ) +{ + if (RtsFlags.ProfFlags.modSelector) { + if (! strMatchesSelector( ccs->cc->module, + RtsFlags.ProfFlags.modSelector ) ) { + ccs->selected = 0; + return; + } + } + if (RtsFlags.ProfFlags.ccSelector) { + if (! strMatchesSelector( ccs->cc->label, + RtsFlags.ProfFlags.ccSelector ) ) { + ccs->selected = 0; + return; + } + } + if (RtsFlags.ProfFlags.ccsSelector) { + CostCentreStack *c; + for (c = ccs; c != NULL; c = c->prevStack) { + if ( strMatchesSelector( c->cc->label, + RtsFlags.ProfFlags.ccsSelector )) { + break; + } + } + if (c == NULL) { + ccs->selected = 0; + return; + } + } + + ccs->selected = 1; + return; +} + + static void initProfilingLogFile(void) { /* Initialise the log file name */ - prof_filename = arenaAlloc(prof_arena, strlen(prog_argv[0]) + 6); - sprintf(prof_filename, "%s.prof", prog_argv[0]); + prof_filename = arenaAlloc(prof_arena, strlen(prog_name) + 6); + sprintf(prof_filename, "%s.prof", prog_name); /* open the log file */ if ((prof_file = fopen(prof_filename, "w")) == NULL) { - fprintf(stderr, "Can't open profiling report file %s\n", prof_filename); + debugBelch("Can't open profiling report file %s\n", prof_filename); RtsFlags.CcFlags.doCostCentres = 0; - // @retainer profiling - // @LDV profiling // The following line was added by Sung; retainer/LDV profiling may need // two output files, i.e., .prof/hp. - if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER || - RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV) + if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER) RtsFlags.ProfFlags.doHeapProfile = 0; return; } @@ -277,12 +291,12 @@ initProfilingLogFile(void) if (RtsFlags.ProfFlags.doHeapProfile) { /* Initialise the log file name */ - hp_filename = arenaAlloc(prof_arena, strlen(prog_argv[0]) + 6); - sprintf(hp_filename, "%s.hp", prog_argv[0]); + hp_filename = arenaAlloc(prof_arena, strlen(prog_name) + 6); + sprintf(hp_filename, "%s.hp", prog_name); /* open the log file */ if ((hp_file = fopen(hp_filename, "w")) == NULL) { - fprintf(stderr, "Can't open profiling report file %s\n", + debugBelch("Can't open profiling report file %s\n", hp_filename); RtsFlags.ProfFlags.doHeapProfile = 0; return; @@ -293,8 +307,6 @@ initProfilingLogFile(void) void initTimeProfiling(void) { - time_profiling = rtsTrue; - /* Start ticking */ startProfTimer(); }; @@ -315,19 +327,19 @@ endProfiling ( void ) -------------------------------------------------------------------------- */ rtsBool entering_PAP; -CostCentreStack * -EnterFunCCS ( CostCentreStack *cccs, CostCentreStack *ccsfn ) +void +EnterFunCCS ( CostCentreStack *ccsfn ) { /* PAP_entry has already set CCCS for us */ if (entering_PAP) { entering_PAP = rtsFalse; - return CCCS; + return; } if (ccsfn->root->is_caf == CC_IS_CAF) { - return AppendCCS(cccs,ccsfn); + CCCS = AppendCCS(CCCS,ccsfn); } else { - return ccsfn; + CCCS = ccsfn; } } @@ -342,9 +354,9 @@ PushCostCentre ( CostCentreStack *ccs, CostCentre *cc ) #define PushCostCentre _PushCostCentre { IF_DEBUG(prof, - fprintf(stderr,"Pushing %s on ", cc->label); - fprintCCS(stderr,ccs); - fprintf(stderr,"\n")); + debugBelch("Pushing %s on ", cc->label); + debugCCS(ccs); + debugBelch("\n")); return PushCostCentre(ccs,cc); } #endif @@ -404,11 +416,11 @@ AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 ) { IF_DEBUG(prof, if (ccs1 != ccs2) { - fprintf(stderr,"Appending "); - fprintCCS(stderr,ccs1); - fprintf(stderr," to "); - fprintCCS(stderr,ccs2); - fprintf(stderr,"\n");}); + debugBelch("Appending "); + debugCCS(ccs1); + debugBelch(" to "); + debugCCS(ccs2); + debugBelch("\n");}); return AppendCCS(ccs1,ccs2); } #endif @@ -448,8 +460,7 @@ static CostCentreStack * ActualPush_ ( CostCentreStack *ccs, CostCentre *cc, CostCentreStack *new_ccs ) { /* assign values to each member of the structure */ - ASSIGN_CCS_ID(new_ccs->ccsID); - + new_ccs->ccsID = CCS_ID++; new_ccs->cc = cc; new_ccs->prevStack = ccs; @@ -469,6 +480,9 @@ ActualPush_ ( CostCentreStack *ccs, CostCentre *cc, CostCentreStack *new_ccs ) new_ccs->root = ccs->root; + // Set the selected field. + ccsSetSelected(new_ccs); + /* update the memoization table for the parent stack */ if (ccs != EMPTY_STACK) ccs->indexTable = AddToIndexTable(ccs->indexTable, new_ccs, cc, @@ -630,7 +644,7 @@ report_per_cc_costs( void ) } } - fprintf(prof_file, "%-20s %-10s", "COST CENTRE", "MODULE"); + fprintf(prof_file, "%-30s %-20s", "COST CENTRE", "MODULE"); fprintf(prof_file, "%6s %6s", "%time", "%alloc"); if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) { fprintf(prof_file, " %5s %9s", "ticks", "bytes"); @@ -641,7 +655,7 @@ report_per_cc_costs( void ) if (cc_to_ignore(cc)) { continue; } - fprintf(prof_file, "%-20s %-10s", cc->label, cc->module); + fprintf(prof_file, "%-30s %-20s", cc->label, cc->module); fprintf(prof_file, "%6.1f %6.1f", total_prof_ticks == 0 ? 0.0 : (cc->time_ticks / (StgFloat) total_prof_ticks * 100), total_alloc == 0 ? 0.0 : (cc->mem_alloc / (StgFloat) @@ -649,7 +663,7 @@ report_per_cc_costs( void ) ); if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) { - fprintf(prof_file, " %5ld %9lld", cc->time_ticks, cc->mem_alloc); + fprintf(prof_file, " %5llu %9llu", (StgWord64)(cc->time_ticks), cc->mem_alloc); } fprintf(prof_file, "\n"); } @@ -664,10 +678,10 @@ report_per_cc_costs( void ) static void fprint_header( void ) { - fprintf(prof_file, "%-24s %-10s individual inherited\n", "", ""); + fprintf(prof_file, "%-24s %-10s individual inherited\n", "", ""); - fprintf(prof_file, "%-24s %-10s", "COST CENTRE", "MODULE"); - fprintf(prof_file, "%8s %5s %5s %5s %5s", "entries", "%time", "%alloc", "%time", "%alloc"); + fprintf(prof_file, "%-24s %-50s", "COST CENTRE", "MODULE"); + fprintf(prof_file, "%6s %10s %5s %5s %5s %5s", "no.", "entries", "%time", "%alloc", "%time", "%alloc"); if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) { fprintf(prof_file, " %5s %9s", "ticks", "bytes"); @@ -681,7 +695,7 @@ fprint_header( void ) } void -report_ccs_profiling( void ) +reportCCSProfiling( void ) { nat count; char temp[128]; /* sigh: magic constant */ @@ -699,13 +713,14 @@ report_ccs_profiling( void ) gen_XML_logfile(); return; default: + break; } fprintf(prof_file, "\t%s Time and Allocation Profiling Report (%s)\n", time_str(), "Final"); fprintf(prof_file, "\n\t "); - fprintf(prof_file, " %s", prog_argv[0]); + fprintf(prof_file, " %s", prog_name); fprintf(prof_file, " +RTS"); for (count = 0; rts_argv[count]; count++) fprintf(prof_file, " %s", rts_argv[count]); @@ -719,9 +734,8 @@ report_ccs_profiling( void ) total_prof_ticks, TICK_MILLISECS); fprintf(prof_file, "\ttotal alloc = %11s bytes", - ullong_format_string((ullong) total_alloc * sizeof(W_), + ullong_format_string(total_alloc * sizeof(W_), temp, rtsTrue/*commas*/)); - /* ToDo: 64-bit error! */ #if defined(PROFILING_DETAIL_COUNTS) fprintf(prof_file, " (%lu closures)", total_allocs); @@ -734,12 +748,6 @@ report_ccs_profiling( void ) fprint_header(); reportCCS(pruneCCSTree(CCS_MAIN), 0); - - // @retainer profiling - // @LDV profiling - // Now, prof_file is closed in shutdownHaskell() because this file - // is also used for retainer/LDV profiling. See shutdownHaskell(). - // fclose(prof_file); } static void @@ -757,19 +765,19 @@ reportCCS(CostCentreStack *ccs, nat indent) /* force printing of *all* cost centres if -P -P */ { - fprintf(prof_file, "%-*s%-*s %-10s", + fprintf(prof_file, "%-*s%-*s %-50s", indent, "", 24-indent, cc->label, cc->module); - fprintf(prof_file, "%8lld %5.1f %5.1f %5.1f %5.1f", - ccs->scc_count, - total_prof_ticks == 0 ? 0.0 : (ccs->time_ticks / (StgFloat) total_prof_ticks * 100), - total_alloc == 0 ? 0.0 : (ccs->mem_alloc / (StgFloat) total_alloc * 100), - total_prof_ticks == 0 ? 0.0 : (ccs->inherited_ticks / (StgFloat) total_prof_ticks * 100), - total_alloc == 0 ? 0.0 : (ccs->inherited_alloc / (StgFloat) total_alloc * 100) + fprintf(prof_file, "%6d %11.0f %5.1f %5.1f %5.1f %5.1f", + ccs->ccsID, (double) ccs->scc_count, + total_prof_ticks == 0 ? 0.0 : ((double)ccs->time_ticks / (double)total_prof_ticks * 100.0), + total_alloc == 0 ? 0.0 : ((double)ccs->mem_alloc / (double)total_alloc * 100.0), + total_prof_ticks == 0 ? 0.0 : ((double)ccs->inherited_ticks / (double)total_prof_ticks * 100.0), + total_alloc == 0 ? 0.0 : ((double)ccs->inherited_alloc / (double)total_alloc * 100.0) ); if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) { - fprintf(prof_file, " %5ld %9lld", ccs->time_ticks, ccs->mem_alloc*sizeof(W_)); + fprintf(prof_file, " %5llu %9llu", (StgWord64)(ccs->time_ticks), ccs->mem_alloc*sizeof(W_)); #if defined(PROFILING_DETAIL_COUNTS) fprintf(prof_file, " %8ld %8ld %8ld %8ld %8ld %8ld %8ld", ccs->mem_allocs, ccs->thunk_count, @@ -885,8 +893,8 @@ reportCCS_XML(CostCentreStack *ccs) cc = ccs->cc; - fprintf(prof_file, " 1 %d %llu %lu %llu", - ccs->ccsID, ccs->scc_count, ccs->time_ticks, ccs->mem_alloc); + fprintf(prof_file, " 1 %d %llu %llu %llu", + ccs->ccsID, ccs->scc_count, (StgWord64)(ccs->time_ticks), ccs->mem_alloc); for (i = ccs->indexTable; i != 0; i = i->next) { if (!i->back_edge) { @@ -908,4 +916,19 @@ fprintCCS( FILE *f, CostCentreStack *ccs ) fprintf(f,">"); } +#ifdef DEBUG +void +debugCCS( CostCentreStack *ccs ) +{ + debugBelch("<"); + for (; ccs && ccs != CCS_MAIN; ccs = ccs->prevStack ) { + debugBelch("%s.%s", ccs->cc->module, ccs->cc->label); + if (ccs->prevStack && ccs->prevStack != CCS_MAIN) { + debugBelch(","); + } + } + debugBelch(">"); +} +#endif // DEBUG + #endif /* PROFILING */