Changes between Version 9 and Version 10 of Commentary/ResourceLimits


Ignore:
Timestamp:
Mar 11, 2013 11:20:24 PM (13 months ago)
Author:
ezyang
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/ResourceLimits

    v9 v10  
    66 
    77{{{ 
    8 type CostCentreStack 
    9 type CostCentre 
     8type CCS 
     9type CC 
    1010type Listener 
    1111 
    12 ccsDynamic :: CostCentreStack 
     12data ProfType = Residence | Allocated 
    1313 
    14 newCostCentre :: IO CostCentre 
    15 pushCostCentre :: CostCentreStack -> CostCentre -> IO CostCentreStack 
    16 setCostCentreStack :: CostCentreStack -> a -> IO () 
    17 listenCostCentreStack :: CostCentreStack -> Int -> IO () -> IO Listener 
    18 unlistenCostCentreStack :: Listener -> IO () 
     14ccsDynamic :: CCS 
     15 
     16newCC :: IO CC 
     17pushCC :: CCS -> CC -> IO CCS 
     18setCCS :: CCS -> a -> IO () 
     19withCCS :: CCS -> IO a -> IO a 
     20listenCCS :: CCS -> ProfType -> Int -> IO () -> IO Listener 
     21unlistenCCS :: Listener -> IO () 
     22getCCSOf :: a -> IO CCS -- already exists 
     23getCurrentCCS :: IO CCS -- already exists 
     24queryCCS :: CCS -> ProfType -> Int 
    1925}}} 
     26 
     27Listeners automatically deregister themselves when they trigger. 
    2028 
    2129The general usage of this API goes like: 
     
    2634    in  sum xs * product xs 
    2735 
    28 newCostCentreStack :: IO CostCentreStack 
    29 newCostCentreStack = pushCostCentre ccsDynamic =<< newCostCentre 
     36newCCS :: IO CCS 
     37newCCS = pushCC ccsDynamic =<< newCC 
    3038 
    3139main = do 
    3240  m <- newEmptyMVar 
    3341  forkIO $ do 
    34     x <- newCostCentreStack 
     42    x <- newCCS 
    3543    tid <- myThreadId 
    36     l <- listenCostCentreStack x 2000 (putStrLn "Too much memory is being used" >> killThread tid) 
    37     let thunk = f 20000 
    38     setCostCentreStack x thunk 
    39     evaluate thunk 
     44    l <- listenCCS x 2000 (putStrLn "Too much memory is being used" >> killThread tid) 
     45    withCCS x $ do 
     46      evaluate (f 20000) 
    4047    unlistenCostCentreStack l 
    4148    putMVar m () 
     
    4956Some points to bikeshed: 
    5057 
    51  * Naming: CostCentreStack/CostCentre or CCS/CC? 
    52  
    53  * Provide {{{withCostCentreStack :: CostCentreStack -> a -> a}}} which is simply a {{{IND_PERM}}} with the CCS set? In my testing, this had to be done very carefully, because if the inner value was a thunk, then this is a no-op 
    54  
    55  * Provide {{{withCostCentre :: CostCentre -> (a -> b) -> (a -> b)}}} which provides the equivalent of function entry (adds the CC to what ever the CCCS is). I don't have a good case for complicated cost-centre stacks and listeners and have not implemented it yet. 
    56  
    57  * Active listeners are considered roots so they must be handled with care to avoid leaks. They should be automatically deregistered to avoid thread bombs. 
    58  
    59  * Another useful thing to measure, besides residency, is overall allocation. Provide an API for that too. 
     58 * Naming: CostCentreStack/CostCentre or CCS/CC? Old API used CCS/CC 
    6059 
    6160 * Instead of the current interface, we could publish STM variables which are updated by the GC; listening is then just an ordinary STM transaction. This might be tricky to implement. 
    62  
    63  * A useful API would be one to just query what the residence of some cost centre is. 
    64  
    65 If we implement something like {{{withCostCentre}}}, we also need to adjust Core slightly. There are two choices: 
    66  
    67  * Modify Tick so that it can take an optional argument (cost-centre); modify the type-checker appropriately. This is not so great because we’re making an already ad hoc addition to the Core language even more complicated, even if the extra typing rules are not that complicated. 
    68  
    69  * Add a new Tickish type, which has no impact on code-generation but still appropriately modifies optimization behavior, and introduce new prim-ops to actually set cost-centers. 
    70  
    71 Note that ordinary (source-generated) ticks could also be converted into prim-ops; but while this sounds appealing, it gets complicated because true source-level SCCs need to be statically initialized (so the runtime system knows about them and can assign an integer ID to them), and moving them into hard-wired constants would complicate the late-stage STG passes. (It's possible, but probably loses out as far as overall complexity goes.) 
    7261 
    7362== Runtime changes == 
    7463 
    7564 * {{{Listener}}} is a new garbage collected object; we expect it can be implemented as a simple {{{PRIM}}} using techniques similar to {{{StgMVarTSOQueue}}}. 
    76  * Checks for listeners occur during heap census; you'll need to pass the {{{-hc}}} flag for this machinery to do anything. See also #7751 which will dramatically improve performance. Right now, running heap census is very slow; if we can make censuses incremental their cost can be amortized with ordinary garbage collector behavior. 
     65 * Checks for listeners occur during heap census; you'll need to pass the {{{-hc}}} flag for this machinery to do anything. Actually, we added a new flag `-hl` which is `-hc` but without writing an `.hp` file. See also #7751 which will dramatically improve performance. Right now, running heap census is very slow; if we can make censuses incremental their cost can be amortized with ordinary garbage collector behavior. 
    7766 
    7867== Commentary == 
    79  
    80 === Support currentCostCentre? === 
    81  
    82 This is obviously fine to support if you are in IO; however, the situation is dicey when considering pure code; an expression {{{currentCostCentre :: CostCentre}}} is not referentially transparent. Rather, we want some semantics like implicit parameters, but no one really likes implicit parameters. Maybe it’s better to only support it in IO (and let someone {{{unsafePerformIO}}} if they reaaally want to.) 
    8368 
    8469=== Interaction with traditional profiling === 
     
    9883=== Callback triple fault === 
    9984 
    100 Finalizer could trigger a new finalizer, ad infinitum. Maybe we don't have to do anything. 
     85Finalizer could trigger a new finalizer, ad infinitum. However, if you don't allocate a new finalizer in the callback, you should be fine. 
    10186 
    10287=== Discussion ===