Multithreading Clojure并行计算阵列

Multithreading Clojure并行计算阵列,multithreading,clojure,parallel-processing,future,Multithreading,Clojure,Parallel Processing,Future,我需要一些帮助。我有一个4000个元素大小的数组(序列)。我需要通过四个不同的函数计算每个部分(1000个元素是一个部分)。在函数计算中,一个部分至少需要10秒。另一个函数在1秒内计算它们的部分。我需要做10次。所以,我当然想同时做。我试着用clojure future来做,但它需要像序列程序一样的计算时间。首先我认为,这是因为当我使用一个数组并向每个函数发送数据时,未来的每个线程都可以依次访问。我如何并行地进行计算 下面是一个简单的代码示例: (defn funct [t n] (let [

我需要一些帮助。我有一个4000个元素大小的数组(序列)。我需要通过四个不同的函数计算每个部分(1000个元素是一个部分)。在函数计算中,一个部分至少需要10秒。另一个函数在1秒内计算它们的部分。我需要做10次。所以,我当然想同时做。我试着用clojure future来做,但它需要像序列程序一样的计算时间。首先我认为,这是因为当我使用一个数组并向每个函数发送数据时,未来的每个线程都可以依次访问。我如何并行地进行计算

下面是一个简单的代码示例:

(defn funct [t n]
 (let [ a (future (fun1 (fun_take_i_part_array n 1)))
        b (future (fun2 (fun_take_i_part_array n 2)))
        c (future (fun3 (fun_take_i_part_array n 3)))
        d (future (fun4 (fun_take_i_part_array n 4)))
      ]
 (concatenate @a @b @c @d)
 )
)


因此,我认为这种未来类型的程序需要比序列最长的时间1秒。

除非这些不是数组而是惰性序列,否则数组访问永远不会是顺序的。不需要这样做,因为数组是不可变的——这是Clojure的显著特点。你的减速并非来自于此

您关于并行化的想法是正确的,请看以下内容:

(defn fibonacci [n] (case n 1 1 2 1 (+ (fibonacci (- n 2)) (fibonacci (- n 1)))))
(defn parallel-fib [] 
        (let [s1 (future (fibonacci 34)) 
              s2 (future (fibonacci 35)) 
              s3 (future (fibonacci 36)) 
              s4 (future (fibonacci 33))] 
 [@s1 @s2 @s3 @s4]))

 user=> (time (fibonacci 35))
 "Elapsed time: 1514.663902 msecs"
 9227465

 user=> (time (fibonacci 36))
 "Elapsed time: 2403.761528 msecs"
 14930352

 user=> (time (parallel-fib))
 "Elapsed time: 2552.572043 msecs"
 [5702887 9227465 14930352 3524578]
很明显,在4核机器上运行的并行执行futures产生的时间接近最昂贵的计算,而不是计算时间的总和

因此,我看不出有什么明显的原因可以解释为什么代码的执行时间更接近顺序执行。我想到的原因可能是:

  • fun1(或任何其他FUN)本身可以是一个并行函数(例如,使用pmap),消耗所有内核。然后,CPU将被填满,并且不会观察到加速

  • 不知何故,“连接”消耗了大量的CPU来将结果放在一起。这不应该是一个大麻烦,因为如果您使用了标准的Clojure“concat”,它会生成一个惰性序列,只有在被访问之后才会产生访问成本。更不用说访问成本应该非常低

  • 如果futures内部的计算非常简单,那么也无法实现良好的缩放。但我们知道这不是真的,因为你已经提到,完成这项工作需要10秒


  • 如果你能把全部代码寄给我,那会有帮助的。我的电子邮件:联系[at]spinney.io.

    每个未来都应该在一个单独的线程中运行。如果
    fun1
    需要10秒,其他3个需要1秒,计算结果仍然需要10秒。因此,使用并行性不会节省很多(实时)时间。请参阅阿姆达尔定律和通用缩放定律。。。