如何在球拍中并行地在列表上映射函数?

时间:2013-03-26 22:26:35

标签: parallel-processing scheme racket

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

2 个答案:

答案 0 :(得分:9)

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

  

Places可以开发利用具有多个处理器,内核或硬件线程的计算机的并行程序。

     

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

可能能够使用其他并行化技术Futures,但它的工作条件相对有限,例如浮点运算,如{{3}所述}。


编辑:回复评论:

  

是否存在使用某处的并行映射的实现?

首先,我应该备份。你可能不需要地方。您可以使用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。有关以“定制”方式使用地点的示例,请参阅:

答案 1 :(得分: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))