質問のタイトルは、本当にすべてを物語っています:ラケットでリストに関数を並列にマップする最良の方法は何ですか? ありがとう。
2 に答える
複数のプロセッサ コアを意味する場合、最も一般的なアプローチはPlacesを使用することです。
プレースを使用すると、複数のプロセッサ、コア、またはハードウェア スレッドを備えたマシンを利用する並列プログラムを開発できます。
プレースは、事実上、Racket 仮想マシンの個別のインスタンスである並列タスクです。プレースは、双方向のバッファー通信のエンドポイントであるプレース チャネルを介して通信します。
他の並列化手法であるFuturesを使用できる場合もありますが、ここで説明されているように、たとえば浮動小数点演算など、動作する条件は比較的限られています。
編集:コメントに応じて:
どこかに場所を使用したパラレルマップの実装はありますか?
まず、バックアップする必要があります。場所は必要ないかもしれません。Racket スレッドを使用して並行性を得ることができます。たとえば、次のようになりますmap/thread
。
#lang racket
(define (map/thread f xs)
;; Make one channel for each element of xs.
(define cs (for/list ([x xs])
(make-channel)))
;; Make one thread for each elemnet of xs.
;; Each thread calls (f x) and puts the result to its channel.
(for ([x xs]
[c cs])
(thread (thunk (channel-put c (f x)))))
;; Get the result from each channel.
;; Note: This will block on each channel if not yet ready.
(for/list ([c cs])
(channel-get c)))
;; Use:
(define xs '(1 2 3 4 5))
(map add1 xs)
(map/thread add1 xs)
I/O リクエストなどのブロッキングを伴う作業が行われている場合、I/O でスタックしないという意味で「並列性」が得られます。ただし、Racket スレッドは「グリーン」スレッドであるため、一度に 1 つのみが CPU を使用します。
複数の CPU コアを並行して使用することが本当に必要な場合は、Future または Places が必要です。
Places の実装方法が原因で --- 実際には Racket の複数のインスタンスとして --- Generic の書き方がすぐにはわかりませんmap/place
。「オーダーメイド」の方法で場所を使用する例については、以下を参照してください。