For Gauche 0.9.12Search (procedure/syntax/module):

Next: , Previous: , Up: ライブラリモジュール - ユーティリティ   [Contents][Index]

12.8 control.pmap - 並列map

Module: control.pmap

このモジュールは、コードを複数スレッドで並列に走らせる高レベルユーティリティを提供します。 例えばpmapは、mapと同様に、 与えられたコレクションの各要素に手続きを適用してその結果をリストにして返しますが、 手続きの適用は並列に行われます。

応用によって望ましい並列化戦略が違うので、仕事の割り振りの戦略をカプセル化する mapperオブジェクトも提供されます。


Function: pmap proc collection :key mapper

{control.pmap} procはひとつの引数を取る手続き、collectionはコレクションです (コレクションフレームワーク参照)。

collectionの各要素に、procを適用します。 適用は複数のスレッドを使って並行して行われるかもしれません。結果はリストにまとめられて返されます。

mapperキーワード引数にmapperを渡すことで、各スレッドにどのように仕事が 割り振られるかをカスタマイズできます。

Function: pfind pred collection :key mapper
Function: pany pred collection :key mapper

{control.pmap} これらは、predを満たす要素を一つ見つけたい時に使えます。 条件に合う要素が見つかった時点で、他のタスクはキャンセルされます。

pfindfindのように、predを満たす要素を見つけたらその要素自身を 返します。一方、panyanyと同じように、 pred#fでない値を返したらその返り値を返します。


predを満たす要素が複数あった場合にどれが返るかは様々な状況に依存するので、 決定的な振る舞いを期待すべきではありません。


mamperはタスクを並列に走らせる戦略をカプセル化したものです。 次のmapperが提供されます。

Static mapper

いくつかのスレッドを作り、タスクを均等に割り振ります。 タスク数が多く、各タスクにかかる時間がそれほど分散しない場合に適しています。 他のマルチスレッドmapperよりもオーバヘッドが少ないです。

Pool mapper

スレッドプールを使ってタスクを処理します。タスク数が多いか、 各タスクの実行にかかる時間の分散が大きい場合に適しています。 また、スレッドプールを再利用することもでき、スレッド作成のオーバヘッドを削減できます。

Fully concurrent mapper

タスクの数だけスレッドを作成して実行します。タスク数がそれほど多くなく、 タスクの中でブロッキングI/Oをする場合に適しています。

Sequential mapper

これは呼び出したスレッド内でタスクを逐次的に実行します。並行実行は行われません。 これには2つの目的があります。(1)シングルコアのシステムでは、 これが最もオーバヘッドの少ない戦略です。(2)並行性による複雑さを除外してアルゴリズムの 動作を確かめるのに使えます。 シングルコアシステムでは、これがdefault-mapperの初期値です。

Parameter: default-mapper

{control.pmap} A parameter keeping a mapper to be used by pmap etc. when no mapper is specified.

The default is a static mapper (with the number of threads same as the number of available cores) if Gauche is configured with threads and the running system has more than one core, or a sequential mapper otherwise.

The mapper set to this parameter is reused, or even is used simultaneously from multiple pmap calls. Pool mappers with external pool keeps a given thread pool in it, so you should be careful ot use such mapper as the default mapper.

Function: sequential-mapper

{control.pmap} Returns a sigleton instance of the sequential mapper.

Function: make-static-mapper :optional num-threads

{control.pmap} Returns a new instance of a static mapper, which spawns num-threads threads on execution, each of which handles evenly divided tasks. This mapper is suitable if you have large number of small tasks with even load.

Function: make-pool-mapper :optional external-pool

{control.pmap} Returns a new instance of a pool mapper, which uses a thread pool (see スレッドプール) to run the tasks. It is suitable when the load of tasks varies a lot.

If external-pool is not given, the mapper creats a thread pool, and shut it down, every time high-level mapping operation is called. This usage is local; that is, the thread pool is contained within one call of pmap etc., and won’t be shared.

Alternatively, you can pass an existing thread pool to external-pool to be used. The pool will be reused every time you use this mapper instance. Using an external pool will eliminate overhead of thread pool creation and shutting down every time you run pmap; however, you have to be aware of those caveats:

Function: make-fully-concurrent-mapper :optional timeout timeout-val

{control.pmap} Returns a new instance of a fully-concurrent mapper, which spawns as many threads as the elements in the given collection to perform the operation concurrently. It is suitable when you don’t have many tasks, but each task may perform blocking I/O calls. The overhead of creating threads are relatively large, but you may be able to utilize CPU more while most of the threads are waiting I/O.

The optional timeout and timeout-val arguments are passed to thread-join! (see スレッド手続き). It is useful when I/O operations may take too long and you want to guarantee the entire operation finishes within certain time limit.

Next: , Previous: , Up: ライブラリモジュール - ユーティリティ   [Contents][Index]

For Gauche 0.9.12Search (procedure/syntax/module):