Haskellの行列計算ライブラリの計算時間を比較

  • 2
    Like
  • 0
    Comment

Haskellで行列計算をしようと思ったときに、どのライブラリを使ったら良いのか迷ったので、代表的なライブラリを使って行列積の計算時間を測定してみました。

Haskellの行列計算ライブラリ

代表的な下記の3ライブラリを対象にします。

行列積の計算プログラム

各ライブラリを使って、要素が1の1000行1000列の行列同士の積を計算して、900行900列目の値を表示するプログラムを用意しました。

matirx

matrix.hs
import Data.Matrix

main = do
    let
        a = matrix 1000 1000 $ \_ -> 1 :: Matrix Double
        b = matrix 1000 1000 $ \_ -> 1 :: Matrix Double
    print $ getElem 900 900 (a `multStd` b)

hmatirx

hmatrix.hs
import Numeric.LinearAlgebra

main = do
    let
        a = (1000 >< 1000) $ replicate (1000 * 1000) 1 :: Matrix Double
        b = (1000 >< 1000) $ replicate (1000 * 1000) 1 :: Matrix Double
    print $ (a <> b) `atIndex` (900, 900)

repa

repa.hs
import Data.Array.Repa
import Data.Array.Repa.Algorithms.Matrix

main = do
    let
        a = fromListUnboxed (Z :. 1000 :. 1000 :: DIM2) $ replicate (1000 * 1000) 1 :: Array U DIM2 Double
        b = fromListUnboxed (Z :. 1000 :. 1000 :: DIM2) $ replicate (1000 * 1000) 1 :: Array U DIM2 Double
    m <- (a `mmultP` b)
    print $ m ! (Z :. 900 :. 900)

計算時間の比較

stackのghcでコンパイルして実行した結果は下記です。

matirx

$ stack ghc matrix.hs
$ time ./matrix
( 1000.0 )


real    0m0.615s
user    0m0.486s
sys     0m0.092s

hmatirx

$ stack ghc hmatrix.hs
$ time ./hmatrix
1000.0

real    0m0.169s
user    0m0.240s
sys     0m0.028s

repa

ghcオプションに-threadedを指定して、実行オプションに+RTS -Nを指定すると、自動的にCPUの全コアを使って並列計算してくれるみたいです。

$ stack ghc -- repa.hs -threaded
$ time ./repa
1000.0

real    0m2.796s
user    0m2.594s
sys     0m0.112s
$ time ./repa +RTS -N
1000.0

real    0m1.652s
user    0m4.552s
sys     0m0.639s

実行環境

GHCのバージョン

$ stack ghc -- --version
...
The Glorious Glasgow Haskell Compilation System, version 8.0.1

PCのスペック

$ system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro11,1
      Processor Name: Intel Core i5
      Processor Speed: 2.4 GHz
      Number of Processors: 1
      Total Number of Cores: 2
      L2 Cache (per Core): 256 KB
      L3 Cache: 3 MB
      Memory: 4 GB
      ...

まとめ

結果的にはhmatrixが圧倒的に速かったです。マルチコアの並列計算が可能なrepaに期待していたのですが、あまり速度は出ませんでした。repaの強みは2次元以上の配列を使う場合、もっと多くのコアを使った場合に出てくるのかもしれません。ひとまず、hmatrixを使うのが無難なのかなと思いました。

参考