Measuring single cost centers

Is it possible profile single SCC’s ? e.g. the result of a given function, after reduction to normal form.

Let’s say I want to analyze `primal` :

let
   tup = f input1 input2
   primal = {-# SCC primal #-} fst $!! tup

Time:

  • .prof files only contain normalized times and allocations, as percentages, e.g. :
mem-bench +RTS -p -RTS

total time  =        0.01 secs   (6 ticks @ 1000 us, 1 processor)
total alloc =   9,873,104 bytes  (excludes profiling overheads)

COST CENTRE                    MODULE                             SRC                                                         %time %alloc

unsafeLinearWrite              Data.Massiv.Array.Manifest.Unboxed src/Data/Massiv/Array/Manifest/Unboxed.hs:(156,3)-(157,74)   16.7    0.0

Is it enough to compute the proportion of total alloc (i.e. scc_time = %time * total_time ) for a given SCC?

Memory:

I imagine one would extract the eventlog with one of the RTS `-l` flags, but documentation on the various eventlog processing tools is quite sparse.

Alternatively, I’ve used `weigh` in the past but it’s incompatible with multithreading and some of my use cases use that feature instead.

Thank you for all pointers!

I think you may be able to answer more profiling questions by loading your profile in https://www.speedscope.app

Profile using the +RTS -pj option and then load the resulting .prof file into the speedscope website.

Some more notes about profiling: GHC Profiling a Cabal Project with an Interactive Application - #2 by romes

2 Likes

Thank you, that works of course, but I have a really hard time parsing flame graphs. I also notice that the SCC’s I defined do not appear anywhere in the flame graph, whereas they appear in the generated JSON file.

What I would like to show is the memory and time dynamics of those specific SCC’s in a dedicated time series plot.

After more investigation, my current understanding is :

  • the eventlog cannot be used for memory profiling of single SCC’s

Memory usage over time cannot be attributed to specific object (this notion might be meaningless in GHC).

BTW This guide to the eventlog and optimization in general and I had totally forgotten about it: 2.6.3. Eventlog | Haskell Optimization Handbook