Changes between Version 16 and Version 17 of NestedCPR


Ignore:
Timestamp:
Jan 8, 2014 4:00:12 PM (19 months ago)
Author:
nomeata
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • NestedCPR

    v16 v17  
    2727  * Possibly because of character reboxing. Try avoiding CPR’ing `C#` alltogether!
    2828
    29 === Degradation explanation ===
     29=== Degradation exploration and explanation ===
    3030
    31 At one point, I thought that a major contributor to increased allocations is nested-CPR’ing things returning `String`, causing them to return `(# Char#, String #)`. But removing the `CPR` information from `C#` calls has zero effect on the allocations, both on `master` and on `nested-cpr`. It had very small (positive) effect on code size. Will have to look at Core... Here are some case studies:
     31At one point, I thought that a major contributor to increased allocations is nested-CPR’ing things returning `String`, causing them to return `(# Char#, String #)`. But removing the `CPR` information from `C#` calls has zero effect on the allocations, both on `master` and on `nested-cpr`. It had very small (positive) effect on code size. Will have to look at Core...
    3232
    33 ==== wave4main ====
     33Here are some case studies with extensive commenting of steps and results:
    3434
    35 Baseline: [0e2fd3/ghc], Tested: nested-cpr (without nesting inside sum-types, without join-point detection).
     35 * [./wave4main]
    3636
    37 Found a 11% increase in allocation, around `9000000` bytes.
     37And here a summary of the problems identified, and solution attempts
    3838
    39 The most obvious change in ticky-ticky-number are:
    40  * `FUNCTION ENTRIES` and `ENTERS` increasing by ~100000
    41  * `RETURNS` doubling from 140745 to 280795
    42  *  `ALLOC_FUN_ctr` and `ALLOC_FUN_gds` almost doubling, by ~18000 resp. 9000000
    43 So we are allocating more function closures. First guess: Join point property destroyed somewhere.
    44 
    45 The ticky output shows a `$wgo{v s60k} (main:Main)` appearing that was not there before, with `140016` enters and `23522688` allocations. This appears in `$wtabulate`, and indeed corresponds to a `go1` that is a join-point before. So what is happening? We are changing
    46 {{{
    47 go1 [Occ=LoopBreaker]                                     
    48   :: GHC.Prim.Int#                                         
    49      -> GHC.Prim.State# s                                 
    50      -> (# GHC.Prim.State# s, GHC.Arr.Array GHC.Types.Int x #)
    51 }}}
    52 to
    53 {{{
    54 $wgo [Occ=LoopBreaker]         
    55   :: GHC.Prim.Int#
    56      -> GHC.Prim.State# s
    57      -> (# GHC.Prim.State# s,   
    58            GHC.Prim.Int#,       
    59            GHC.Prim.Int#,       
    60            GHC.Prim.Int#,       
    61            GHC.Prim.Array# x #)
    62 }}}
    63 
    64 `go1` is recursive, but tail-recursive, so the worker and wrapper indeed cancel for the recursive call. But where it is being used, we simply apply the `Array` constructor to the second component. So nothing is gained, but a join-point is lost.
    65 
     39 * CPR kill join-points, because the wrapper does not completely cancel with anything else.
     40   - Detecting join-points at the position of its binding is not enough.
     41 * A recursive function can have a CPR-beneficial recursive call that makes CPR worthwhile, even if it does not help at the initial call. But it is also not unlikely that the recursive call is a tail-call, and CPR-ing has zero effect on that. Then it all depends on the external call.
    6642
    6743=== join points ===