我在确定非阻塞线程池大小时看到的两个最常见的默认值是:
number of threads = number of cores
number of threads = number of cores + 1
但现在我在Vert.x找到了另一个,即:
number of threads = 2 * number of cores
显然logic behind this value是因为Java无法将特定线程固定到特定核心,如果我们设置# threads == # cores
,我们可能会浪费一些可用的核心。从理论上讲,通过将# threads
设置为类似2 * # cores
的内容,使用所有内核的概率会增加。
我不确定我是否对此论点深信不疑,因为我希望操作系统调度程序能够尝试在内核中找到最佳的工作分配。它可能不是最佳分布,但我希望它比具有常数乘数更好。
我知道这一切都取决于正在执行的任务的类型,但是,假设没有阻塞IO(因此不需要让非活动线程等待资源的大量时间),2 * # cores
是更好的默认值方法比# cores
?为什么呢?
答案 0 :(得分:2)
Java线程的权威书籍(Java Concurrency in Practice)说:
对于计算密集型任务,Ncpu处理器系统通常使用Ncpu +1线程的线程池实现最佳利用率。 (即使是计算密集型线程偶尔也会出现页面错误或因某些其他原因而暂停,因此一个"额外的可运行线程会阻止CPU周期在发生这种情况时不使用。)
根据我的实验,这是正确的(即使没有I / O,Ncpu +1也略好于Ncpu,但进一步增加线程数没有任何好处)。
当然,在具体情况下,你应该总是测量:)
答案 1 :(得分:2)
唯一明确的答案是对每一个进行分析,因为行为取决于目标系统上运行的内容以及所涉及的代码。
如果所有线程都达到相同的时间,那么(2 *个核心)将导致更多的上下文切换,这可能会导致惩罚。
还有一点点相关,是一个名为OpenHFT的Java线程关联库 - 它使用本机代码 - 允许您将线程绑定到特定的核心。