Changes between Version 16 and Version 17 of NestedCPR


Ignore:
Timestamp:
Jan 8, 2014 4:00:12 PM (14 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 ===