Haskellによる並列・並行プログラミング

[cover photo]
TOPICS
Programming
発行年月日
PRINT LENGTH
328
ISBN
978-4-87311-689-1
原書
Parallel and Concurrent Programming in Haskell
FORMAT
PDF EPUB
Ebook
3,960円
Ebookを購入する

並列・並行プログラミングはプログラマの重要な関心事であり、常に注目を集めている話題です。これまで、関数型言語は並列・並行プログラミングに有利であると言われてきましたが、それを説明する書籍はありませんでした。本書では、純粋関数型言語Haskellが提供する並列・並行プログラミングの機能を俯瞰し、実践的な問題を解いていきます。その根底にある考え方は、関数プログラミングの核心であるモジュラリティです。また本書では、実際の問題を解決するときに陥りがちな落とし穴や、高い性能を出すためのtipsなどをまとめています。

正誤表

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

1刷正誤表


Haskellによる並列・並行プログラミング 第1刷正誤表

2016年4月8日更新

位置
p.viii
下から
5行目
ます。4、5、6、14章
 では、
ます。4、5、6、14章では、
※改行削除
p.viii
最終行
13章はまず部を読んでから 13章はまず部を読んでから
p.4
下から
4行目
% cabal configure
$ cabal build
$ cabal configure
$ cabal build
p.6
下から
9行目
「データフロー並列:Parモナド」 4章 データフロー並列:Parモナド
p.21
下から
11行目
の2つが出力されます。 の2つが出力されます。
p.25
3行目
不均一の原因は、 不均一の原因は、
p.29
見出し
2.4 Deepseq 2.4 DeepSeq
p.30
2行目
Control.Deepseqモジュールでは、 Control.DeepSeqモジュールでは、
p.53

3行目
リストの要素は遅延ByteStringsですから、 リストの要素は遅延ByteStringですから、
p.59
❸❹
1つ目の計算は、fig nの値をIVar iに代入して、
2つ目の計算は、fig mの値をIVar jに代入します。
1つ目の計算は、fig nの値をIVariに代入して、
2つ目の計算は、fig mの値をIVarjに代入します。
p.67
下から
7行目
遅延ByteStringsを消費、 遅延ByteStringを消費、
p.68
脚注
sa.hsプログラムの rsa.hsプログラムの
p.90
下から
7行目
computeS適用する必要があります。 computeS適用する必要があります。
p.91
見出し
直下
「4.2 例:グラフの最短路」 「4.1 例:グラフの最短路」
p.98
1行目
つまり、関数f つまり、関数f
p.100
1行目
fifjれぞれ画像の fifjれぞれ画像の
p.103
本文
2行目
GPUm(Graphics Processing Unit) GPU(Graphics Processing Unit)
p.110
12行目
generateを作成できます。 generateが使えます。
p.114
囲み
最終行
「6.10.3 CUDAバッグエンドのデバッグ」で簡単に説明します。 「6.9.2 CUDAバッグエンドのデバッグ」で簡単に説明します。
p.122
6行目
「5.6 例:画像の回転」で説明した 「5.5 例:画像の回転」で説明した
p.126
見出し
直下
指定した時間が経過したことを報せるプログラムために 指定した時間が経過したことを報せるプログラムために
p.131
下から
8行目
抜けたときにはプログラム直ちに停止 抜けたときにはプログラム直ちに停止
p.135
下から
7行目
示されています。どんな純粋な 示されています。どんな純粋な
※書体変更
p.140
中央
unGetCharの実装方法を考えてみましょう。 unGetChanの実装方法を考えてみましょう。
p.141
下から
16行目
ブロックされ、操作が同じMVarに対して ブロックされ、同じMVarに対して
p.145
それぞれ要素に関数を適用します。 それぞれ要素に関数を適用します。
p.158
下から
9行目
ThredIdの値は直前のforkIO呼び出しが返す値で、 ThredIdの値はThrowToよりも前にあるforkIO呼び出しが返す値で、
p.160

2行目
表示されるでしょう。 表示されるでしょう。
p.162
10行目
problemにおいてtakeMVarんだ後、同じMVarに対して別のスレッドがputMVarを呼ぶかもしれないからです。本当に空であるは、 problemにおいてtakeMVarんだ後、同じMVarに対して別のスレッドがputMVarを呼ぶかもしれないからです。本当に空であるは、
p.166
最終行
ここで(1) ここで1.
p.178
下から
13行目
先に読んでから書き込まなければ 先に読んでから書き込まなければ
p.181
❸直下
putMVarの実装は簡単です。 putTMVarの実装は簡単です。
p.192
7行目
パターンマッチしようとすると、 パターンマッチしようとすると、
p.194
TIP中
コード
thread 2:
  atomically $ writeTBQueue q2 y
  atomically $ writeTBQueue q1 x]
thread 2:
  atomically $ writeTBQueue q2 y
  atomically $ writeTBQueue q1 x
p.195
下から
8行目
putMVarがどのように動くかを考えましょう。 putTMVarがどのように動くかを考えましょう。
p.196
6行目
IOアクションを返すSTMトランザクションです。 IOアクションを返すSTMトランザクションです。
※書体変更

目次

目次


訳者まえがき
まえがき

1章 はじめに
    1.1 用語:並列性と並行性
    1.2 ツールとリソース
    1.3 サンプルコード

I部 並列Haskell

2章 基本の並列性:Evalモナド
    2.1 遅延評価と弱頭部正規形
    2.2 Evalモナド、rpar、rseq
    2.3 例:並列数独ソルバ
    2.4 Deepseq

3章 評価戦略
    3.1 戦略の並列化
    3.2 リストを並列に評価する戦略
    3.3 例:K平均法
        3.3.1 K平均法の並列化
        3.3.2 性能と分析
        3.3.3 スパーク活動の可視化
        3.3.4 粒度
    3.4 GCされるスパークと投機的並列性
    3.5 parBufferを使った遅延ストリームの並列化
    3.6 チャンク分け戦略
    3.7 同一性特性

4章 データフロー並列:Parモナド
    4.1 例:グラフの最短路
    4.2 パイプライン並列
        4.2.1 生産者の流量制限
        4.2.2 パイプライン並列の制限
    4.3 例:会議の時間割
        4.3.1 並列性の追加
    4.4 例:並列型推論器
    4.5 別のスケジューラを使う
    4.6 戦略と比較したParモナド

5章 Repaを用いたデータ並列プログラミング
    5.1 配列、シェイプ、添字
    5.2 配列に対する操作
    5.3 例:最短路の計算
        5.3.1 プログラムの並列化
    5.4 畳み込みとシェイプ多相
    5.5 例:画像の回転
    5.6 まとめ

6章 AccelerateによるGPUプログラミング
    6.1 概要
    6.2 配列と添字
    6.3 単純なAccelerate計算を実行する
    6.4 スカラ配列
    6.5 配列に添字でアクセスする
    6.6 Accの中で配列を作る
    6.7 2つの配列を綴じ合わせる
    6.8 定数
    6.9 例:最短路問題
        6.9.1 GPU上で実行する
        6.9.2 CUDAバックエンドのデバッグ
    6.10 例:マンデルブロ集合の生成器

II部 並行Haskell

7章 並行制御の基本:スレッドとMVar
    7.1 例:備忘通知
    7.2 通信:MVar
    7.3 簡単なチャネルとしてのMVar:ログサービス
    7.4 共有状態としてのMVar
    7.5 組み立て部品としてのMVar:無制限チャネル
    7.6 公平性

8章 入出力の重ね合わせ
    8.1 Haskellの例外
    8.2 Asyncのエラー処理
    8.3 マージ

9章 キャンセルとタイムアウト
    9.1 非同期例外
    9.2 非同期例外のマスク
    9.3 bracket
    9.4 チャネルに対する非同期例外の安全性
    9.5 タイムアウト
    9.6 非同期例外の捕捉
    9.7 maskとforkIO
    9.8 非同期例外に関して

10章 ソフトウェアトランザクショナルメモリ
    10.1 ウィンドウマネージャの例
    10.2 ブロッキング
    10.3 変更されるまでのブロッキング
    10.4 STMを使ったマージ
    10.5 Async再考
    10.6 STMを使ったチャネルの実装
        10.6.1 より多くの操作が可能
        10.6.2 ブロックされる操作の合成
        10.6.3 非同期例外安全
    10.7 もう1つのチャネル実装
    10.8 有界チャネル
    10.9 STMでできないこと
    10.10 性能
    10.11 まとめ

11章 並行性の高水準な抽象化
    11.1 スレッド漏れの回避
    11.2 対称型並行性コンビネータ
        11.2.1 raceを使ったタイムアウト
    11.3 Functorインスタンスの追加
    11.4 まとめ:Async API

12章 並行ネットワークサーバ
    12.1 簡単なサーバ
    12.2 単純なサーバの状態による拡張
        12.2.1 設計1:1つのジャイアントロック
        12.2.2 設計2:サーバスレッドごとに1つのチャネル
        12.2.3 設計3:放送チャネルの利用
        12.2.4 設計4:STMの利用
        12.2.5 実装
    12.3 チャットサーバ
        12.3.1 アーキテクチャ
        12.3.2 クライアントのデータ
        12.3.3 サーバのデータ
        12.3.4 サーバ
        12.3.5 新しいクライアントの準備
        12.3.6 クライアントの起動
        12.3.7 まとめ

13章 スレッドを用いた並列プログラミング
    13.1 並行性を用いて並列性を達成する方法
    13.2 例題:ファイル探索
        13.2.1 直列版
        13.2.2 並列版
        13.2.3 性能とスケール
        13.2.4 セマフォを使ったスレッド数の制限
        13.2.5 ParIOモナド

14章 分散プログラミング
    14.1 distributed-processパッケージファミリー
    14.2 分散並行性か分散並列性か
    14.3 最初の例:ピン(ping)
        14.3.1 プロセスとProcessモナド
        14.3.2 メッセージ型の定義
        14.3.3 ピンサーバのプロセス
        14.3.4 マスタープロセス
        14.3.5 main関数
        14.3.6 例題のまとめ
    14.4 複数ノードでのピン
        14.4.1 1つのマシン上で複数のノード
        14.4.2 複数のマシン
    14.5 型付きチャネル
        14.5.1 チャネルのマージ
    14.6 失敗処理
        14.6.1 分散プログラムにおける失敗の哲学
    14.7 分散チャットサーバ
        14.7.1 データ型
        14.7.2 メッセージ送信
        14.7.3 放送
        14.7.4 配布
        14.7.5 サーバのテスト
        14.7.6 失敗とノードの追加/削除
    14.8 練習問題:分散KVS

15章 デバッグ、チューニング、外部コードとのインタフェース
    15.1 並行プログラムのデバッグ
        15.1.1 スレッド状態の検査
        15.1.2 イベントログとThreadScope
        15.1.3 デッドロックの検出
    15.2 並行(および並列)プログラムのチューニング
        15.2.1 スレッドの生成とMVar操作
        15.2.2 並行データ構造の共有
        15.2.3 微調整のためのRTSオプション
    15.3 並行性と外部関数インタフェース
        15.3.1 スレッドと外部呼び出し
        15.3.2 非同期例外と外部呼び出し
        15.3.3 スレッドと外部からの呼び出し

索引