f# - Why do prints to console get mixed up when doing parallel computations? -


while running code performs parallel computations output becomes garbled: different messages mixed up. here sample:

iteration 1 iteration iteration 23 of 19 - calculating p&l test window ending @ 10/28/1968 12:00:00   of iteration 4 iteration  of iteration 5 iteration iteration 19 - calculating p&l test window ending @  of 19 - calculating p&l test window ending @ 5/29/1974 12:00:00 6 of 878/18/1971 12:00:00 am19 - calculating p&l test window ending @ 3/4/1977 12:00:00    of 19 of  of 19 - calculating p&l test window ending @ 6/25/1985 12:00:00 

when running same program sequentially console output comes out nice, no garbling.

printing console done function:

let windowtraintest (comm: communication) critfoo count (model: imodel) (assets: assets) (paramlist: parameters list) =     // deleted code here     if comm = verbose         let msg1 = sprintf "\nwindowtraintestpandl: first date: %a, last date: %a\nbest criterion: %.2f\n" fdate ldate bestcriterion         let msg2 = sprintf "best parameters: %a\n" bestparameters          printfn "%s" <| msg1 + msg2      (pandl, wgts), bestparameters, ( ["criterion", bestcriterion]            |> map.oflist,                                      ["firstdate", fdate; "lastdate", ldate] |> map.oflist ) 

parallelization done portion of program:

let pseqmapi f (xs: seq<'t>) = xs |> pseq.mapi f  let traintest n (trainsize, fullsize) =         let takenassets = assets |> assets.take (min fullsize len)         lastdate takenassets         |> printfn "\niteration %d of %d - calculating p&l test window ending @ %a\n" (i + 1) n         paramlist         |> windowtraintest comm' critfoo trainsize model takenassets      let maptraintest (initsizes: (int * int) list) =         let f = traintest initsizes.length         match calctype         | pseq -> initsizes |> pseqmapi f |> list.ofseq         | _    -> initsizes |> seq.mapi f |> list.ofseq 

is there way avoid kind of behavior, example flushing message console?

parallel computations run on different threads, , if 1 thread interrupted in middle of printfn , second thread runs printfn before first thread gets run again, outputs interleaved.

the simplest way deal create new function use lock keyword around printfn invocations:

let lockobj = new obj() let lockedprintfn msg = lock lockobj (fun _ -> printfn msg) 

then replace printfn calls lockedprintfn , should serialized output you're expecting. performance suffer little since threads spending time waiting printfn lock, long computations take longer time spent printing output, shouldn't notice slightly-slower performance.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -