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

欢迎!请参阅关于页面以了解有关该功能的更多信息。

0
Clojure

pmap的代码创建了(future %) coll的集合操作所需的前景,然后在任何给定时间显然保留仅#CPUs+2未完成前景的方式中对该序列进行处理。对于未分块的输入序列,它确实以这种方式工作,但当pmap传递一个分块序列时,前景序列也变成了分块。这导致了任意数量的前景因为#CPUs+2窗口和块大小窗口之间的交互而被实现。

pmap的文档字符串没有承诺任何特定的并行级别,但我认为分块与未分块输入不一致的并行性是一个bug。

8 个回答

0
by

评论由:stu做出

下一个人深入研究pmap时,可能也需要考虑fork/join。

0
by

评论由:jim.blomo做出

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

0
by

评论由:jafingerhut做出

Clojure/core团队的成员可以提供更权威的观点,但我相信,随着最近基于jsr166代码的reduce增强,Clojure 1.5可能会需要Java 6或更高版本,Java 5将不再受到支持。

0

评论由:jim.blomo做出

在任务受CPU限制时,启动比CPU核心更多的线程不是一个好主意。目前(1.4版本)pmap使用无界线程池,因此分块序列将创建比预期的更多线程。最微不足道的改变是使用固定大小的线程池(ForkJoinPool是一个例子)。pmap与core.reducers的区别在于它是惰性的。这意味着它使用了逐个提交的ThreadPool.submit模型,而不是递归的fork/join模型。权衡包括

即使在分块序列上也强制进行预览
- + 无需更改threadPool
- - 违背分块的意图,这可能是出于某个原因在使用的

切换到固定大小线程池
- + 减少分块序列上cpu限制函数的竞争
- - 增加io限制函数的总实现时间

使用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
参考: https://clojure.atlassian.net/browse/CLJ-862(由 llasram 提出)
...