评论者: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作为固定大小的线程。
让我知道如果我忘记了或理解错误了什么。