J Fritsch
J Fritsch

Reputation: 3358

Haskell and Multicore, what is really happening

I try to understand what is really happening when you want to make use of more than one core in Haskell. This gives a nice introduction but IMHO is not very critical and leaves many questions open.

When I use the par combinator or forkIO in my code and compile it with the -threaded flag, what eventually decides whether I get an OS thread or not? Is it the compiler or the OS?

If I use forkOS that should always create an OS thread, does that liberate me from the capabilities of the underlying OS?

To clarify my question: I assume that in a multicore world the underlying/installed OS has limitations in regard of how many cores it can make sense of and use. Is everything that I do in Haskell truncated by the capabilities of the OS? Or, are there any ways (what are they?) to be better than the OS in a sense that if a host has 12 cores and the OS masters 8, can I push that any further by writing a smart applications in Haskell or will then everything I run on this host with this OS be limited to the smart use of 8 cores?

Upvotes: 2

Views: 601

Answers (2)

none
none

Reputation: 21

  1. to get four OS threads you'd use the option +RTS -N4 -RTS in your command line when you run the program. To get a different number than 4, you'd just substitute it. By default (the non-threaded runtime) you'd get just one OS thread, though you can run lots of GHC's lightweight IO threads within it. With -N4, the runtime launches 4 total threads when the program starts up, and then IO threads are handed off to them.

  2. Yes, you can start an OS thread explicitly with forkOS. The reason you might want to do that is if you're calling a C function through the FFI, that might use blocking I/O and would freeze other lightweight threads if it ran in the same OS threads. Otherwise let the runtime handle OS threads.

  3. You should probably read Haskell concurrency-related articles starting here:

Upvotes: 2

Dietrich Epp
Dietrich Epp

Reputation: 213298

The Haskell runtime decides how many OS threads to create. The OS decides how to map those threads to physical cores and processors. The compiler really has nothing to do with it, I think...

There are some layers here. (Note that the compiler isn't in this diagram.)

+-----------------+
|    User code    |
+-----------------+
         |
         | forkIO creates
         v
+-----------------+
| Haskell threads |
+-----------------+
         |
         | Runtime library maps to
         v
+-----------------+
|   OS Threads    |
+-----------------+
         |
         | OS scheduler runs on
         v
+-----------------+
| Physical cores  |
+-----------------+

The OS will never create an OS thread for you, that's not it's job. The OS only does what your application and the runtime library instruct it to do. The OS can only schedule runtime for existing OS threads on physical cores.

The runtime library chooses how many OS threads are created as well as what parts of your code run on which thread. You have some control over it, but one of its functions is to map your code to OS threads.

As you can see, if an OS is limited to using 8 cores then there is no way you can use 12. You cannot bypass OS limitations. However, modern OSs support more cores than you have, so don't worry. (If you are using Windows XP, you are stuck with 2 cores. But it is silly to run Windows XP on a machine with more than 2 cores.)

Upvotes: 10

Related Questions