8

问题标题确实说明了一切:在球拍中将函数映射到并行列表的最佳方法是什么?谢谢。

4

2 回答 2

9

如果您的意思是多个处理器内核,那么最通用的方法是使用Places

Places 支持开发利用具有多个处理器、内核或硬件线程的机器的并行程序。

地点是一个并行任务,它实际上是 Racket 虚拟机的一个单独实例。场所通过场所通道进行通信,场所通道是双向缓冲通信的端点。

也许可以使用另一种并行化技术Futures,但它的工作条件相对有限,例如浮点运算,如此处所述


编辑:回应评论:

是否有在某处使用地点的并行地图实现?

首先,我应该备份。您可能不需要 Places。您可以使用 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 线程是“绿色”线程,因此一次只有一个线程会使用 CPU。

如果您确实需要并行使用多个 CPU 内核,那么您将需要 Futures 或 Places。

由于 Places 的实现方式——有效地作为多个 Racket 实例——我没有立即看到如何编写泛型map/place. 有关以“定制”方式使用地点的示例,请参阅:

于 2013-03-26T23:56:38.720 回答
2

我不知道在 Racket 中,但我在SISC Scheme中实现了一个版本。

(define (map-parallel fn lst)
  (call-with-values (lambda ()
                      (apply parallel 
                             (map (lambda (e)
                                    (delay (fn e)))
                                  lst)))
    list))

只是parallel不是R5RS。

使用示例:

使用常规map

(time (map (lambda (a)
        (begin
          (sleep 1000)
          (+ 1 a)))
     '(1 2 3 4 5)))
=> ((2 3 4 5 6) (5000 ms))

使用map-parallel

(time (map-parallel (lambda (a)
        (begin
          (sleep 1000)
          (+ 1 a)))
     '(1 2 3 4 5)))
=> ((2 3 4 5 6) (1000 ms))
于 2015-09-18T04:23:54.090 回答