2024 Clojure 状况调查! 中分享您的看法。

欢迎!请参阅 关于 页面以了解如何使用此功能的一些更多信息。

0 投票
Clojure

pmap 代码创建所需的 map 操作集的 futures,然后以显然旨在在任何给定时间只保持 #CPUs+2 个未完成 futures 的方式作用于该序列。对于非分块输入序列,它确实以这种方式工作,但当一个分块序列传递给 pmap 时,future 序列也会被分块。这导致当 #CPUs+2 窗口和分块大小窗口交互时,会有任意数量的 futures 被实现。

关于 pmap 的文档字符串并没有承诺任何特定的并行级别,但我觉得分块输入与未分块输入之间不一致的并行级构成了一个错误。

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的不同之处在于它是惰性的,这意味着采用单个线程池.submit的模式,而不是递归的fork/join模式。权衡包括

即使对于分块序列也强制进行前瞻
- + 没有threadPool的更改
- - 与分块(可能被用于某个原因)作对抗

切换到固定大小的线程池
- + 减少了分块序列上CPU受限函数的竞争
- - 增加了I/O受限函数的总实现时间

使用ForkJoinPool作为固定大小的线程池(而不是newFixedThreadPool)
- + 自动和动态并行性
- - 更复杂的配置(选择Java 6与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日的patch pmap-chunking-862.diff在2014年1月11日对Clojure master的最新提交后已经不纯净地应用了。我认为唯一的问题是添加的测试已经改变了上下文行,因此如果有人想要更新补丁,应该是一个快速的修复。

0 投票

评论人:jim.blomo

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

0 投票
参考:[https://clojure.atlassian.net/browse/CLJ-862](由 llasram 报告)
...