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 - 它使用本机代码 - 允许您将线程绑定到特定的内核。
我在调整非阻塞线程池大小时看到的两个最常见的默认值是:
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 - 它使用本机代码 - 允许您将线程绑定到特定的内核。