How does forkIO and par interact?

Hello, How does forkIO (forkOS) and par interact with one another? Here is why I ask. I have a GUI application that has something like this: th <- forkIO (guiCode + longRunningPureSerialCode) Later, a user interaction invokes killThread th and the guiCode plus the longRunningPureSerialCode suspends quite nicely. Now I have th <- forkIO (guiCode + longRunningPureParallelCode) Later a user interaction invokes killThread th again but I have observed under 6.10.4 that not all is suspended. From what I have observed, I believe that if longRunningPureParallelCode = ... 1stPart `par` 2ndPart ... the 2ndPart is suspended by killThread th along with the guiCode, and the 1stPart happily continues calcualting. (I believe this is correct but it could be the other way around.) For my little application, having everything suspend would have been nice, but that's my app. So, under ghc, how is forkIO (forkOS) and par supposed to operationally interact with one another? Cheers, - Marcus

Hello Marcus, Sunday, December 20, 2009, 4:17:26 PM, you wrote: par adds so-called spark to the queue of calculations to proceed. once RTS has free thread, this thread starts to calculate the spark. it has no communication with thread that created the spark. when calculation is completed, its thunk will be updated with result of calculation (as usual in lazy calculations). so killing originator thread doesn't affect all the sparks it has created, it only prevents generation of new sparks
Hello,
How does forkIO (forkOS) and par interact with one another? Here is why I ask.
I have a GUI application that has something like this:
th <- forkIO (guiCode + longRunningPureSerialCode)
Later, a user interaction invokes
killThread th
and the guiCode plus the longRunningPureSerialCode suspends quite nicely. Now I have
th <- forkIO (guiCode + longRunningPureParallelCode)
Later a user interaction invokes killThread th again but I have observed under 6.10.4 that not all is suspended. From what I have observed, I believe that if
longRunningPureParallelCode = ... 1stPart `par` 2ndPart ...
the 2ndPart is suspended by killThread th along with the guiCode, and the 1stPart happily continues calcualting. (I believe this is correct but it could be the other way around.)
For my little application, having everything suspend would have been nice, but that's my app.
So, under ghc, how is forkIO (forkOS) and par supposed to operationally interact with one another?
Cheers, - Marcus
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Thanks Bulat. What you wrote makes perfect sense to me. However under 6.10.4 this is what I observed. Pseudo code: c = l++r `demanding` l>||r then th <- forkIO (c `seq` return ()) Run it the first time to completion and watch two cores turn at better than 95% utilisation, quite pleasing. Run it the second time and half way through the calculation use killThread th and watch one core become idle and one core turn at better than 95%. Wait until the first core finishes and then use c and watch the rest of the calculation finish. Now, what you wrote and this experiment tells me that l was sparked and then given a free thread in which to calculate. r was still in the original thread of execution of the forkIO and therefore was affected by the killThread th whereas l was not. Does this read correct to you? If so, then I understand! Thanks, - Marcus Bulat Ziganshin wrote:
Hello Marcus,
Sunday, December 20, 2009, 4:17:26 PM, you wrote:
par adds so-called spark to the queue of calculations to proceed. once RTS has free thread, this thread starts to calculate the spark. it has no communication with thread that created the spark. when calculation is completed, its thunk will be updated with result of calculation (as usual in lazy calculations). so killing originator thread doesn't affect all the sparks it has created, it only prevents generation of new sparks. -- Marcus D. Gabriel, Ph.D. Saint Louis, FRANCE http://www.marcus.gabriel.name mailto:marcus@gabriel.name Tel: +33.3.89.69.05.06 Portable: +33.6.34.56.07.75

On 20/12/2009 14:12, Marcus D. Gabriel wrote:
Thanks Bulat. What you wrote makes perfect sense to me. However under 6.10.4 this is what I observed. Pseudo code:
c = l++r `demanding` l>||r
then
th<- forkIO (c `seq` return ())
Run it the first time to completion and watch two cores turn at better than 95% utilisation, quite pleasing. Run it the second time and half way through the calculation use
killThread th
and watch one core become idle and one core turn at better than 95%. Wait until the first core finishes and then use c and watch the rest of the calculation finish.
Now, what you wrote and this experiment tells me that l was sparked and then given a free thread in which to calculate. r was still in the original thread of execution of the forkIO and therefore was affected by the killThread th whereas l was not.
Does this read correct to you? If so, then I understand!
That's exactly right, yes. In principle we could have spark threads be garbage collected if their results aren't shared by the main program. In practice that's hard to determine, since sharing is not an all-or-nothing question. There's a fruitful line of research here, though, since it affects how well you can express speculation. Cheers, Simon
participants (3)
-
Bulat Ziganshin
-
Marcus D. Gabriel
-
Simon Marlow