17

Does Haskell have a method for determining the number of CPU cores present on a machine at runtime?

Steve Severance
  • 6,611
  • 1
  • 33
  • 44

5 Answers5

18

Yes, there is such a method. Code from "Real World Haskell": http://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html

import GHC.Conc (numCapabilities)

main = putStrLn $ "number of cores: " ++ show numCapabilities
Viktor Dahl
  • 1,942
  • 3
  • 25
  • 36
  • 17
    Note that (as the book states) this only gives you the number of cores supplied to the RTS via `-N`, which is not necessarily equal to the number of physical cores. –  Nov 07 '11 at 20:02
  • It's the number of cores that Haskell will be allowed to access...which is almost certainly what the OP actually wants? – Louis Wasserman Nov 07 '11 at 23:17
  • @LouisWasserman: I can see use cases where a program may wish to make use of as many cores as required (without being explicitly granted permission to do so). Alternatively, someone may wish to write a program to obtain hardware statistics. – ivanm Nov 08 '11 at 12:14
  • But they *couldn't* use any more cores than the number supplied to the RTS via -N, even if they wanted to. The second case you describe is the only other case I can imagine. – Louis Wasserman Nov 08 '11 at 20:32
  • 6
    @LouisWasserman Another case is a make-like program that wants to start up N external processes, where N = number of cores, but itself uses only a single capability (with `-threaded`, so that FFI calls don't block the whole process). – Mikhail Glushenkov Jan 07 '12 at 10:18
16

Since base 4.5 you can use getNumProcessors from GHC.Conc. This is good since the number of capabilities can now be set dynamically with setNumCapabilities from the same.

jberryman
  • 16,334
  • 5
  • 42
  • 83
6

You could copy'n'paste this code into a file called numCores and compile it with your Haskell code. Than you can use the FFI to import its definition and use it directly in your Haskell code:

{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Applicative ((<$>))
import Foreign.C.Types (CInt)

foreign import ccall "getNumCores" c_getNumCores :: IO CInt
getNumCores :: IO Int
getNumCores = fromEnum <$> c_getNumCores
Community
  • 1
  • 1
fuz
  • 88,405
  • 25
  • 200
  • 352
6

Since version 6.12, GHC RTS includes a function getNumberOfProcessors, which is used to implement +RTS -N. You can access it in much the same manner as ordinary foreign functions. Warning: GHC-only and only works if the program was built with -threaded:

{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.Types (CInt)

foreign import ccall "getNumberOfProcessors" c_getNumberOfProcessors :: IO CInt

main :: IO ()
main = c_getNumberOfProcessors >>= print

Testing:

$ ghc --make -threaded Main.hs
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking Main ...
$ ./Main                      
1
Mikhail Glushenkov
  • 14,928
  • 3
  • 52
  • 65
-1

It is GHC.Conc.getNumProcessors :: IO Int. The getNumCapabilities tells how many threads are suggested to GHC (and depends on +RTS -N option parameter.)

Michal Gajda
  • 603
  • 5
  • 13