Java 无阻塞的最佳默认线程数 I/O

Java optimal default number of threads without blocking I/O

我在调整非阻塞线程池大小时看到的两个最常见的默认值是:

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 之类的值,使用所有内核的可能性会增加。

我不确定我是否被这个论点说服,因为我希望 OS 调度程序会尝试找到跨核心的最佳工作分配。它可能不是最佳分布,但我希望它比使用常数乘数更好。

我知道这完全取决于正在执行的任务类型,但是,假设没有阻塞 IO(因此不需要让非活动线程为资源等待大量时间),2 * # cores# cores 更好的默认方法?为什么?

Java 线程的权威书籍(Java 并发实践)说:

For compute-intensive tasks, an Ncpu-processor system usually achieves optimum utilization with a thread pool of Ncpu +1 threads. (Even compute-intensive threads occasionally take a page fault or pause for some other reason, so an "extra" runnable thread prevents CPU cycles from going unused when this happens.)

根据我的实验,这是真的(Ncpu +1 比 Ncpu 稍微好一点,即使没有 I/O,但进一步增加线程数没有任何好处)。

当然,在具体情况下你应该总是衡量:)

唯一确定的答案是分析每个,因为行为取决于目标系统上 运行 的内容以及涉及的代码。

如果所有线程获得相同的时间,拥有 (2*cores) 将导致更多的上下文切换,这可能会导致惩罚。

还有一点相关, Java 的线程关联库,称为 OpenHFT - 它使用本机代码 - 允许您将线程绑定到特定的内核。