2024年Clojure调查!中分享你的想法。

欢迎!请参阅关于页面以了解更多关于如何使用本网站的信息。

0
Clojure

pmap的代码为其需要执行的map操作集合创建未来的(future %) coll,然后以显然打算保持任何时候只有 #CPUs+2 个未完成的未来的方式作用于该序列。对于非分块输入序列,它是这样的,但当pmap传递一个分块序列时,未来的序列也会分块。这导致当 #CPUs+2 窗口和块大小窗口相互作用时,会实现任意数量的未来。

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-05-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 报告)
...