2024年Clojure状态调查!分享您的想法。

欢迎!请访问关于页面以获取有关此如何工作的更多信息。

0
Clojure

pmap的代码为需要执行的map操作集创建futures,然后以某种明显 intend to keep only #CPUs+2 unfinished futures realized at any given time的方式作用于这个序列。对于非分块输入序列,它确实以这种方式工作,但当pmap传递一个分块序列时,futures序列也会变成分块的。这导致任意数量的futures被 realized,因为#CPUs+2窗口和分块大小窗口交互。

pmap的doc-string没有承诺特定的并行级别,但我认为分块输入和非分块输入之间不一致的并行性是一个bug。

8 答案

0

评论者:stu

下一个深入研究pmap的人可能也需要深思fork/join。

0

评论者:jim.blomo

fork/join是Java 7的功能。一个提议的补丁需要能够回退到Java 5功能吗?

0

评论者:jafingerhut

Clojure的核心开发者可以更权威地声明,但我相信随着最近依赖jsr166代码的reduce增强,Clojure 1.5很可能需要Java 6或更高版本,并且Java 5将不再受支持。

0

评论者:jim.blomo

当工作受CPU限制时,启动比CPU核心数量更多的线程并不是一个好主意。目前(1.4版)pmap使用一个无界的线程池,因此分块序列将会创建比预期更多的线程。做出的最微创变是使用固定大小的线程池(ForkJoinPool就是一个例子)。pmap与core.reducers的区别在于它是惰性的。这意味着它采用单线程提交模型,而不是递归的分解/合并模型。权衡包括

即使在分块序列中强制预览
- + 不需要更改threadPool
- - 与分块作对,而分块可能是出于某种原因而使用的

转移到固定大小线程池
- + 减少分块序列上CPU绑定函数的竞争
- - 增加I/O密集型函数的总实现时间

使用ForkJoinPool作为固定线程池(而不是newFixedThreadPool)
- + 自动和动态并行
- - 更复杂的设置(选择Java 6 vs 7实现,与core.reducers共享池)

我认为使用传统的固定大小线程池是正确选择。大多数时候,pmap的所有结果都将被实现,所以我认为没有必要对预览大小过于严格。这也是决策map所做的决定。由于我们没有使用ForkJoin的主要优势(递归工作队列),我认为在clojure.core中设置它并不值得。

我将对Agent/pooledExecutor作为固定大小的线程。

如果有什么遗漏或误解的地方,请通知我。

0

评论者:jim.blomo

2012年5月28日的pmap-chunking-862.diff使用了固定大小线程池处理pmap函数。

0

评论者:jafingerhut

2012年5月28日的pmap-chunking-862.diff补丁在2014年1月11日对Clojure master的最新提交之后不再干净地应用。我认为唯一的问题是添加的测试改变了上下文行,所以如果有人想要更新补丁,应该是一个快速的修复。

0

评论者:jim.blomo

感谢你的更新,Andy。这个月我会尝试解决这个问题。

0
by
参考资料:https://clojure.atlassian.net/browse/CLJ-862(由llasram报告)
...