Haskell による並列・並行プログラミング #6 担当: lotzさん
p.85 5章 Repaを用いたデータ並列プログラミング
ここまではEvalとParを見てきた
ボックス化されたデータ
配列に関してはアンボックス化されたほうが効率が良い
アンボックス化された配列をうまく扱えるのがRepa
p.86 5.1 配列、シェイプ、添字
ghciでの数値リテラルに対する型注釈が面倒なら :set -XExtendedDefaultRules するのも手
と思ったけど数値リテラルがIntegerになると困るので型注釈を書いたほうが良さそう
:i で型の定義が見れて便利
code:haskell
data Array
r -- representation
sh -- shape
e -- element type
例えば Array U DIM2 Int 二次元Int配列のUnboxed Vector表現
toIndex シェイプとインデックスを取って1次元上のインデックスを返す
reshape シェイプと配列を取って、指定したシェイプの配列を返す
rank 配列の次元数
size 配列の要素数
extent 配列からシェイプを取り出す
p.86 5.2 配列に対する操作
Repa.map 表現がDにかわる(Delayed)
Dのものは勝手にShowされないようにされている(No instanceエラーが出る)
computeS シーケンシャルに計算
Load: 遅延されている(計算中)みたいなニュアンスを出す型クラス
Target: 計算が完了さているニュアンスを出す型クラス
Delayする意味は?
複数の計算を実行する時に、逐一計算して配列を作ると効率が悪い
先に関数を合成する(融合)ことで効率よく計算する
fromFunction シェイプと、シェイプに対する関数から配列を作る
mapもfromFunctionから作れる
mymap f a = fromFunction (extent a) (\ix -> f (a ! ix))
p.91 5.3 例:最短路の計算
直列版
cabal build --ghc-options="-O2" -- fwdense
-fllvm オプションは私の今の環境では使えなかった
cabal exec -- fwdense 500 +RTS -s
1.940s
並列版(1コア)
cabal exec -- fwdense1 500 +RTS -s
2.230s
並列版(4コア)
cabal exec -- fwdense1 500 +RTS -s -N4
0.661s
computeP で並列化
Monadicな関数になっている
並列に評価されている要素を更に並列評価しようとするとWarningが出る
複数回 computeP を呼び出すときは、一番外側で run するべき。
次回
担当: lotzさん