Debugging/LowLevelProfiling/PAPI: NofibanalyseWithPAPI.diff

File NofibanalyseWithPAPI.diff, 10.2 KB (added by simonmar, 3 years ago)
  • utils/nofib-analyse/Main.hs

    Thu Dec 21 12:55:36 CET 2006  Alexey Rodriguez <mrchebas@gmail.com>
      * Ability to read counter stats
    diff -rN -u old-ghc/utils/nofib-analyse/Main.hs new-ghc/utils/nofib-analyse/Main.hs
    old new  
    119119mreads_spec  = SpecP "Memory Reads" "Reads" "mem-reads" mem_reads run_status always_ok 
    120120mwrite_spec  = SpecP "Memory Writes" "Writes" "mem-writes" mem_writes run_status always_ok 
    121121cmiss_spec   = SpecP "Cache Misses" "Misses" "cache-misses" cache_misses run_status always_ok 
     122cpu_counter_spec counter extract = SpecP counter counter counter (mean extract) run_status always_ok 
     123 
     124mk_cpu_counter_specs rs wantGC = map (uncurry cpu_counter_spec) countersAndSelectors 
     125    where 
     126      predWantGC ('G':'C':_,_) = wantGC 
     127      predWantGC _ = not wantGC 
     128      -- We retain the counters we're interested in 
     129      countersAndSelectors = filter predWantGC (zip counters selectors) 
     130      -- Counter names obtained from a nofib run 
     131      counters = map fst . 
     132                 get_counters . 
     133                 cpu_counters . 
     134                 head . 
     135                 Map.elems . 
     136                 head $ rs -- Are there CPU counters there? 
     137      -- How to access counter data 
     138      selectors = [ selIth i . get_counters . cpu_counters | i<-[0..] ] 
     139      selIth i ls | length ls <= i = [] 
     140                  | otherwise = snd (ls !! i) 
    122141 
    123142all_specs = [ 
    124143  size_spec, 
     
    381400  . (if (length results == 2) 
    382401        then ascii_summary_table False results summary_spec summary_rows . str "\n\n" 
    383402        else id) 
    384   . interleave "\n\n" (map (asciiGenProgTable results args) per_prog_result_tab) 
     403  . interleave "\n\n" (map (asciiGenProgTable results args) (counters_specs ++ per_prog_result_tab)) 
    385404  . str "\n" 
    386405  . interleave "\n\n" (map (asciiGenModTable results args)  per_module_result_tab) 
    387406  ) "\n" 
     407    where 
     408      -- Report specifications for counters 
     409      counters_specs = mk_cpu_counter_specs results False ++ 
     410                       mk_cpu_counter_specs results True 
    388411 
    389412asciiGenProgTable results args (SpecP title _ anc get_result get_status result_ok) 
    390413  = str title  
     
    756779 
    757780interleave s = foldr1 (\a b -> a . str s . b)  
    758781 
    759 fIELD_WIDTH = 16 :: Int 
     782fIELD_WIDTH = 25 :: Int 
    760783 
    761784----------------------------------------------------------------------------- 
  • utils/nofib-analyse/Slurp.hs

    diff -rN -u old-ghc/utils/nofib-analyse/Slurp.hs new-ghc/utils/nofib-analyse/Slurp.hs
    old new  
    44-- 
    55----------------------------------------------------------------------------- 
    66 
    7 module Slurp (Status(..), Results(..), ResultTable, parse_log) where 
     7module Slurp (Status(..), Results(..), ResultTable, parse_log, get_counters, CpuCounters) where 
    88 
    99import CmdLine 
    1010 
     
    2727        | Exit Int 
    2828        | WrongStdout 
    2929        | WrongStderr  
     30          deriving Show 
    3031 
    3132data Results = Results {  
    3233        compile_time    :: Map String Float, 
     
    4344        gc_time         :: [Float], 
    4445        allocs          :: Maybe Integer, 
    4546        run_status      :: Status, 
    46         compile_status  :: Status 
    47         } 
     47        compile_status  :: Status, 
     48        cpu_counters    :: CpuCounters 
     49        } deriving Show 
     50 
     51data CpuCounters 
     52    = CpuCCalculated [(String,[Float])] -- Probably horribly inneficient but somehow flexible. 
     53    | CpuCEmpty 
     54    | CpuCError -- Inconsistent counters, probably ran with different counter options, so we ignore it. 
     55      deriving Show 
    4856 
    4957emptyResults = Results {  
    5058        compile_time    = Map.empty, 
     
    6169        gc_work         = Nothing, 
    6270        allocs          = Nothing, 
    6371        compile_status  = NotDone, 
    64         run_status      = NotDone 
     72        run_status      = NotDone, 
     73        cpu_counters    = CpuCEmpty 
    6574        } 
    6675 
    6776----------------------------------------------------------------------------- 
     
    104113ghc3_re = GHC 4.03 (includes "xxxx bytes GC work") 
    105114-} 
    106115 
    107 ghc1_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+) bytes GC work, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) :ghc>>" 
     116ghc1_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+) bytes GC work, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) (\\[.*\\] )?:ghc>>" 
    108117 
    109 ghc2_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+)M in use, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) :ghc>>" 
     118ghc2_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+)M in use, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) (\\[.*\\] )?:ghc>>" 
    110119 
    111 ghc3_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+) bytes GC work, ([0-9]+)M in use, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) :ghc>>" 
     120ghc3_re = mkRegex "^<<ghc:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+) bytes GC work, ([0-9]+)M in use, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\) (\\[.*\\] )?:ghc>>" 
    112121 
    113122ghc4_re = mkRegex "^<<ghc-instrs:[ \t]+([0-9]+)[ \t]+bytes,[ \t]*([0-9]+)[ \t]+GCs,[ \t]*([0-9]+)/([0-9]+)[ \t]+avg/max bytes residency \\(([0-9]+) samples\\), ([0-9]+) bytes GC work, ([0-9]+)M in use, ([0-9.]+) INIT \\(([0-9.]+) elapsed\\), ([0-9.]+) MUT \\(([0-9.]+) elapsed\\), ([0-9.]+) GC \\(([0-9.]+) elapsed\\), ([0-9]+) instructions, ([0-9]+) memory reads, ([0-9]+) memory writes, ([0-9]+) L2 cache misses :ghc-instrs>>" 
    114123 
     
    143152                      cache_misses = cm1, 
    144153                      gc_time = gt1, gc_work = gw1, 
    145154                      binary_size = bs1, allocs = al1,  
    146                       run_status = rs1, compile_status = cs1 } 
     155                      run_status = rs1, compile_status = cs1 , 
     156                      cpu_counters = cpuc1 } 
    147157             Results{ compile_time = ct2, link_time = lt2,  
    148158                      module_size = ms2, 
    149159                      run_time = rt2, mut_time = mt2, 
     
    151161                      cache_misses = cm2, 
    152162                      gc_time = gt2, gc_work = gw2, 
    153163                      binary_size = bs2, allocs = al2,  
    154                       run_status = rs2, compile_status = cs2 } 
     164                      run_status = rs2, compile_status = cs2 , 
     165                      cpu_counters = cpuc2 } 
    155166          =  Results{ compile_time   = Map.unionWith (flip const) ct1 ct2, 
    156167                      module_size    = Map.unionWith (flip const) ms1 ms2, 
    157168                      link_time      = combMaybes lt1 lt2, 
     
    166177                      binary_size    = combMaybes bs1 bs2, 
    167178                      allocs         = combMaybes al1 al2, 
    168179                      run_status     = combStatus rs1 rs2, 
    169                       compile_status = combStatus cs1 cs2 } 
     180                      compile_status = combStatus cs1 cs2, 
     181                      cpu_counters   = combCpuCounters cpuc1 cpuc2 } 
    170182 
    171183combMaybes m1 m2 = case maybeToList m1 ++ maybeToList m2 of 
    172184                        [] -> Nothing 
    173185                        (x:_) -> Just x 
    174186 
     187combCpuCounters :: CpuCounters -> CpuCounters -> CpuCounters 
     188combCpuCounters CpuCError _ = CpuCError 
     189combCpuCounters _ CpuCError = CpuCError 
     190combCpuCounters CpuCEmpty c = c 
     191combCpuCounters c CpuCEmpty = c 
     192combCpuCounters (CpuCCalculated cs1) (CpuCCalculated cs2) 
     193    = foldr mergeCounter (CpuCCalculated []) $ zip cs1 cs2 
     194      where 
     195        mergeCounter ((n1,ss1),(n2,ss2)) (CpuCCalculated ls) 
     196            | n1 == n2 = CpuCCalculated ((n1,ss1++ss2) : ls) 
     197        mergeCounter _ CpuCError = CpuCError 
     198 
     199get_counters CpuCError = [] 
     200get_counters CpuCEmpty = [] 
     201get_counters (CpuCCalculated ls) = ls 
     202 
     203 
    175204combStatus NotDone x = x 
    176205combStatus x NotDone = x 
    177206combStatus x y = x 
     
    278307parse_run_time prog [] res ex = [(prog, res{run_status=ex})] 
    279308parse_run_time prog (l:ls) res ex = 
    280309        case matchRegex ghc1_re l of { 
    281            Just (allocs:_:_:_:_:init:_:mut:_:gc:_) -> 
     310           Just (allocs:_:_:_:_:init:_:mut:_:gc:_:cpu:_) -> 
    282311                got_run_result allocs init mut gc Nothing 
    283                         Nothing Nothing Nothing Nothing; 
     312                        Nothing Nothing Nothing Nothing (mk_counter cpu); 
    284313           Nothing ->  
    285314 
    286315        case matchRegex ghc2_re l of { 
    287            Just (allocs:_:_:_:_:_:init:_:mut:_:gc:_) -> 
     316           Just (allocs:_:_:_:_:_:init:_:mut:_:gc:_:cpu:_) -> 
    288317                got_run_result allocs init mut gc Nothing 
    289                         Nothing Nothing Nothing Nothing; 
     318                        Nothing Nothing Nothing Nothing (mk_counter cpu); 
    290319 
    291320            Nothing -> 
    292321         
    293322        case matchRegex ghc3_re l of { 
    294            Just (allocs:_:_:_:_:gc_work:_:init:_:mut:_:gc:_) -> 
     323           Just (allocs:_:_:_:_:gc_work:_:init:_:mut:_:gc:_:cpu:_) -> 
    295324                got_run_result allocs init mut gc (Just (read gc_work)) 
    296                         Nothing Nothing Nothing Nothing; 
     325                        Nothing Nothing Nothing Nothing (mk_counter cpu); 
    297326 
    298327            Nothing -> 
    299328         
     
    301330           Just (allocs:_:_:_:_:gc_work:_:init:_:mut:_:gc:_:is:mem_rs:mem_ws:cache_misses:_) -> 
    302331                got_run_result allocs init mut gc (Just (read gc_work)) 
    303332                        (Just (read is)) (Just (read mem_rs)) 
    304                         (Just (read mem_ws)) (Just (read cache_misses)); 
     333                        (Just (read mem_ws)) (Just (read cache_misses)) CpuCEmpty; 
    305334 
    306335            Nothing -> 
    307336         
     
    330359 
    331360        }}}}}}}} 
    332361  where 
    333   got_run_result allocs init mut gc gc_work instrs mem_rs mem_ws cache_misses 
     362  mk_counter "" = CpuCEmpty -- Assumming that a non-matching '?' regexp returns empty 
     363  mk_counter s  = CpuCCalculated (read s) 
     364  got_run_result allocs init mut gc gc_work instrs mem_rs mem_ws cache_misses counters 
    334365      = -- trace ("got_run_result: " ++ init ++ ", " ++ mut ++ ", " ++ gc) $ 
    335366        let  
    336367          read_mut = read mut 
     
    346377                                        mem_reads  = mem_rs, 
    347378                                        mem_writes = mem_ws, 
    348379                                        cache_misses = cache_misses, 
    349                                         run_status = Success  
     380                                        run_status = Success, 
     381                                        cpu_counters = counters 
    350382                                } 
    351383        in 
    352384        parse_run_time prog ls res' Success