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

欢迎!有关如何使用本网站的信息,请参阅关于页面。

0
Clojure

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

pmap 的文档字符串没有承诺任何特定的并行级别,但我认为对于分块输入和非分块输入不一致的并行性包含了一个错误。

8 答案

0

由 stu 发布的评论

将深入了解 pmap 的下一个人可能还需要考虑 fork/join。

0

由 jim.blomo 发布的评论

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

0

由 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 模型。权衡包括

即使对于分块序列,也要强制预览
没有改造线程池
减少了对分块的困难,而分块可能因某个原因而被使用

转向固定大小的线程池
减少分块序列上 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日的补丁文件 pmap-chunking-862.diff 在2014年1月11日提交给 Clojure master 的最新提交之后不再干净地应用。我认为唯一的问题是添加的测试更改了上下文行,因此如果有人想更新补丁,那么这将是一个快速修复。

0

由 jim.blomo 发布的评论

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

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