我刚刚开始在Clojure中编写以下代码,用于通过蒙特卡罗模拟估算pi。我基本上想要创建X线程,每个线程计算落在单位圆中的随机点数并返回它。然后我的主线程将它们全部加起来并计算Pi。
但是,在同一个线程中运行所有样本比通过future在多个线程之间拆分计算更快。为什么呢?
(defn sumFutures [workerFutures acc i]
(if (= -1 i)
acc
(recur workerFutures (+ acc @(nth workerFutures i)) (dec i))))
(defn getResults [workerFutures numSamples]
(* 4.0 (/ (sumFutures workerFutures 0 (dec (count workerFutures))) numSamples)))
(defn isInCircle []
(let [x (rand) y (rand)]
(if (<= (+ (* x x) (* y y)) 1)
1
0)))
(defn countInCircle [remaining acc]
(if (zero? remaining)
acc
(recur (dec remaining) (+ acc (isInCircle)))))
(defn getWorker [samplesPerWorker]
(future
(countInCircle samplesPerWorker 0)))
(defn addWorker [workers samplesPerWorker]
(conj workers (getWorker samplesPerWorker)))
(defn getWorkers [workers samplesPerWorker remWorkers]
(if (not (zero? remWorkers))
(recur (addWorker workers samplesPerWorker) samplesPerWorker (dec remWorkers))
(doall workers)))
(defn main [numSamples numWorkers]
(getResults (getWorkers [] (quot numSamples numWorkers) numWorkers) numSamples))
;; Run all in 1 thread
(main 1000000 1)
;; Split among 100 futures (at least 8 threads)
;; SLOWER
(main 1000000 100)
基于调试结果的其他几个注释:
正在创建正确的期货数量
每个未来都在计算正确的模拟数量
这是在多个线程和处理器核心上运行
答案 0 :(得分:0)
如果您将第二次运行中的期货数量减少到2(和8),会发生什么?管理线程和期货的时间可能大于分割工作所节省的时间。
产生比硬件可支持的更多线程通常会产生相反的效果(因为线程必须共享内核并且需要付出代价)。如果你只用两个线程来获得速度增益(与1相比),那么其他地方可能出现了问题。