【问题标题】:Java optimal default number of threads without blocking I/OJava 不阻塞 I/O 的最佳默认线程数
【发布时间】:2015-01-29 19:22:37
【问题描述】:

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

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?为什么?

【问题讨论】:

标签: java multithreading operating-system jvm vert.x


【解决方案1】:

Java 线程的权威书籍(Java Concurrency in Practice)说:

对于计算密集型任务,Ncpu 处理器系统通常通过 Ncpu +1 线程的线程池实现最佳利用率。 (即使是计算密集型线程也偶尔会出现页面错误或因其他原因暂停,因此“额外的”可运行线程可以防止 CPU 周期在这种情况下未被使用。)

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

当然,在具体情况下,您应该始终测量 :)

【讨论】:

  • Re,“...即使没有 I/O。”:您引用的段落告诉您即使有 I/O,也有 is “没有 I/O”。分页也是 I/O。
  • @jameslarge 是的。我的意思是代码中没有显式的 I/O。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多